4 tips om PHP6 compatible code te schrijven
Iedereen die een beetje met PHP werkt weet hopelijk nu wel dat PHP4 vanaf het eind van dit jaar niet meer ondersteund zal worden door de ontwikkelaars. Dat is natuurlijk vervelend voor de mensen die nu nog gebruik maken van PHP4 maar het wordt nu dus toch echt tijd om te gaan upgraden.
Vervolgens staat PHP6 ook al in de planning, dus als je inderdaad vanaf PHP4 af komt is het verstandig om nu alvast rekening te gaan houden met PHP6. In dit artikel leer je hoe nu voor PHP 5.2 al code kunt schrijven die compatibel blijft met PHP6.
1. Besef dat Unicode er aan komt
Dé feature van PHP6 is natuurlijk native Unicode ondersteuning. Hoewel deze functionaliteit deels uitgeschakeld kan worden is het vaak gunstig om met Unicode te gaan werken. Zeker wanneer je plannen hebt voor meerdere talen in je website.
Een van de belangrijkste kenmerken van Unicode waar je rekening mee zult gaan moeten houden is het feit dat in een encoding van Unicode, zoals bijvoorbeeld UTF-8, een karakter niet perse bestaat uit 1 byte. Karakters uit bijvoorbeeld het cyrillisch, arabisch of japanse alfabet kunnen 1 tot en met 4 bytes aan geheugen innemen.
Tot en met PHP 5 heeft PHP geen benul gehad van unicode (behalve wellicht met de mbstring extensie). Dit houdt in dat PHP 5 intern altijd werkt met het concept dat 1 karakter maximaal 1 byte groot is. In PHP 6 begrijpt PHP unicode en hoeft 1 karakter dus niet meer perse 1 byte groot te zijn. Dit zorgt voor een verandering in gedrag in alle string functies, zoals het volgende voorbeeld laat zien:
-
mathieu@ubuntu:~/public_html/utf8$ php5 index.php
-
PHP 5.1.6
-
strlen('Хорошее утро') = 23
-
-
mathieu@ubuntu:~/public_html/utf8$ php index.php
-
PHP 6.0.0-dev
-
strlen('Хорошее утро') = 12
Oftewel, in PHP 5 geeft strlen() het aantal bytes in de string terwijl in PHP6 strlen() het aantal karakters geeft. In de meeste gevallen gaat dit geen probleem zijn voor je. Zeker niet wanneer je een site alleen in de Nederlandse taal ontwikkelt, maar er zijn situaties denkbaar waar je het gedrag van PHP5 wilt behouden.
Denk bijvoorbeeld aan een situatie waarbij je met binaire data werkt. Wanneer je met binaire data werkt, wil je de individuele bytes en niet de individuele karakters kunnen aanspreken. Een reeks willekeurige bytes kunnen mogelijkerwijs als een paar UTF-8 karakters gezien worden. Ga je vervolgens aan de slag met functies als substr() dan kan het zijn dat je 4 bytes terug krijgt terwijl je maar 1 byte verwachtte! Dat kan natuurlijk de nodige problemen oproepen.
Daarom zijn er in PHP 6 twee string types in het leven geroepen. Je hebt een gewone, unicode string en een binaire string. Met een unicode string geeft strlen() het aantal karakters terug, terwijl met een binaire string je het aantal bytes krijgt. Om een binaire string te maken plaats je simpelweg een 'b' voor je string, of je kunt een (bestaande) unicode string casten naar een binaire string.
-
// PHP6:
-
$unicodeStr = "unicode string"; // Geen extra syntax: dit wordt een unicode string
-
$binaryStr = b"binary string"; // Een 'b' voor de string definieert deze string als een BINARY string.
-
-
$binaryStrCast = (binary) "unicode string"; // De 'binary' cast operator cast de string naar een binary string
Het mooie is dat deze syntax ook al te gebruiken is in PHP 5.2 en het is dus aan te raden om wanneer je werkt met binaire data nu alvast aan te geven welke strings perse niet als unicode string benaderd moeten worden. Het gebruik van deze syntax heeft in PHP 5.2 verder geen effect, maar ga je op een gegeven moment over naar PHP6 dan zullen alle niet gemarkeerde strings gezien worden als een Unicode string, terwijl die gemarkeerd zijn als Binary blijven werken zoals verwacht.
2. Vergeet register_globals
Als je nog gebruik maakt van de feature register_globals, de feature die alle variabelen die van buiten komen - zoals GET,POST en COOKIE variabelen - in de global scope registreert, wordt het nu echt tijd om over te schakelen op de superglobals die in PHP 4.2 zijn geintroduceerd. register_globals wordt in z'n geheel uit PHP6 gehaald.
Het verwijderen van deze feature houdt óók in dat enkele functies, die gebaseerd waren op register_globals functionaliteit, niet meer zullen bestaan.
- Verwijderde functies:
- session_register()
- session_unregister()
- session_is_registered()
- Waarschuwingen bij:
- gebruik van de INI setting: register_global
3. Vergeet magic_quotes
Nog een feature die uit PHP6 is verwijderd is, is de magic_quotes feature. Wanneer geactiveerd voorzag de magic quotes feature de verschillende variabelen die van buiten kwamen, zoals GET, POST en COOKIE variabelen, van slashes wanneer er in deze string gebruik werd gemaakt van backslashes, NULL karakters, apostrofs of aanhalingstekens. Dit om eventuele SQL injectie en/of cross site scripting te voorkomen. Echter schakelde sommige ontwikkelaars en hosters deze functionaliteit uit, waardoor je als software ontwikkelaar eigenlijk toch altijd voor beide gevallen moest programmeren.
Deze feature wordt volledig verwijderd uit PHP6. Om code te schrijven die compatibel blijft met zowel PHP5 als PHP6 (en dus moet controleren of magic_quotes_gpc aan staat of niet) raad ik je aan om met de functie ini_get() te kijken of magic_quotes feature geactiveerd is:
Ik dacht eigenlijk dat de functies get_magic_quotes_gpc() en get_magic_quotes_runtime() voorlopig nog zouden blijven bestaan maar dan altijd FALSE retourneren. Echter lijkt geen van deze 2 functies nog te bestaan in een recente snapshot van PHP6.
-
Verwijderde functies:
- get_magic_quotes_gpc()
- get_magic_quotes_runtime()
- set_magic_quotes_runtime()
-
Waarschuwingen bij:
- gebruik INI setting 'magic_quotes_gpc'
- gebruik INI setting 'magic_quotes_runtime'
- gebruik INI setting 'magic_quotes_sybase'
4. Vergeet de $HTTP_*_VARS variabelen
Voordat de zeer praktische super globals werden toegevoegd in PHP 4.2 hadden de ontwikkelaars van PHP het probleem van register_globals opgelost door middel van de zogenaamde "Register Long Arrays" functionaliteit. Dit zijn de variabelen met de namen $HTTP_GET_VARS, $HTTP_POST_VARS, enzovoorts.
Aangezien deze variabelen zijn overschaduwd door de superglobals $_GET, $_POST, $_COOKIE, $_ENV, $_SERVER en $_SESSION worden ze dus compleet verwijderd uit PHP6.
Mensen die $HTTP_RAW_POST_DATA gebruiken wordt aangeraden om over te stappen op het gebruik van php://input .
-
<?php
-
-
if ($_SERVER['REQUEST_METHOD'] == 'POST')
-
{
-
}
-
-
?>
- Waarschuwingen bij: gebruik INI settings 'register_long_arrays'
Conclusie
Hoewel deze 4 tips je kunnen helpen om je code vooraf meer compatibel te maken, is het natuurlijk niet gegarandeerd dat alle code die zich enkel aan deze 4 tips houden ook daadwerkelijk goed blijft werken in PHP6. Het is daarom belangrijk om, als je mee wilt met PHP6, nu alvast te gaan testen met PHP6.
Dagelijks geupdate test versies van PHP6 zijn te downloaden vanaf snaps.php.net.
Volg Scriptorama via RSS!
Reageer ook!
Nu nog method overloading en PHP wordt volwassen. :)
Door Alex Kamsteeg
op 11.11.07 @ 3:25 pm | Permalink
Ach, als je -echt- method overloading nodig hebt kun je dat nu al realiseren, sinds PHP4 al. Daarbij, een strategy implementatie is in sommige gevallen misschien wel beter.
Door Mathieu Kooiman
op 11.11.07 @ 3:55 pm | Permalink
Ja, je kan predefined parameters gebruiken, maar een echt nette oplossing vind ik dat niet.
Door Alex Kamsteeg
op 11.11.07 @ 4:17 pm | Permalink
Method overloading lijkt opzig interessant maar probleem ontstaat dan dat je snel een fout maakt met een type, en je dit eigenlijk min of meer al hebt.
Gewoon de parameters van de functie uitlezen en kijken wat voor type het is.
Door Sebastiaan Stok
op 11.11.07 @ 4:24 pm | Permalink
En dan moet je natuurlijk ook nog rekening mee houden dat er geen safe mode meer bestaat.
> Method overloading lijkt opzig interessant
> maar probleem ontstaat dan dat je snel een
> fout maakt met een type, en je dit eigenlijk
> min of meer al hebt.
Mja, nadeel zal blijven dat PHP loosely typed is. Daarmee is het echte voordeel van method overloading (zoals in Java) dan ook nog ver weg.
Door Berry Langerak
op 11.11.07 @ 6:51 pm | Permalink
[...] Die toekomst is PHP6, en ondanks alle voorbereiding blijkt deze devel setup toch niet toereikend om juiste PHP6 code te schrijven. Toevallig las ik op scriptorama.nl een artikel met enkele tips over php6 code development. Ik houdt me al een tijd bezig met het omprogrammeren van een grote php4 applicatie naar php5, php4 wordt namelijk eind dit jaar afgeschreven. Ik zit natuurlijk niet te wachten om dit over een paar jaar nog een keer te doen. Zo las ik in het scriptorama artikel dat magic_quotes_gpc support uit php6 verdwijnt, ondanks dat deze nu standaard aan staat. Magic Quotes heb ik altijd een fantastische optie in php gevonden, en een groot voordeel voor live servers. De beredenering van het schrappen is dat sommige hostingproviders dit uitschakelen en dat daarom programmeurs dit voor beide gevallen zou moeten programmeren. Ik ben het hier niet mee eens, omdat de magic quotes gewoon veel veiligheids problemen voorkomen op live servers, en zeker voor shared hosting servers. Volgens mij is de hint bij programmeurs vrij duidelijk aangekomen, door het standaard uitschakelen van deze optie in de php.ini-recommanded. Het lijkt mij dus ook dat php6 niet snel breed gebruikt zal worden, al is het alleen maar vanwege het risico dat de shared hosters nemen met php programmatuur waar ze geen zicht op hebben. [...]
Door Beaart’s gedachten » php development op 11.19.07 @ 11:55 pm | Permalink
"Ik ben het hier niet mee eens, omdat de magic quotes gewoon veel veiligheids problemen voorkomen op live servers, en zeker voor shared hosting servers."
Als je gegevens in de database plaats hoor je daarbij gewoon de door voor bedoelde functies te gebruiken niet gewoon slashes toe te voegen.
De correct escaping van SQL is '' en niet \'.
Voor de mensen die lui zijn heb ik nog een leuke work-around.
Maar alsjeblieft, doe het nu gewoon op de goede manier :)
Door Sebastiaan Stok
op 11.23.07 @ 11:06 am | Permalink
Is het waar dat de functie mysql_query() ook verwijderd zal worden uit PHP6 ?
Dit zou een erg vervelende kwestie zijn gezien in sommige van mijn applicaties wel 100 maal of meer dan dat zelfs gebruik wordt gemaakt van die functie. Kan me erg goed voorstellen dat dat bij andere ontwikkelaars niet anders is. Ik heb naar bevestigingen gezocht maar kan er erg weinig over vinden anders dan dat er sprake van zou zijn bij de ontwikkelaars van de PHP engine en dan volgens een niet nader te noemen Nederlandstalige PHP-gerelateerde site.
Door Ray
op 12.13.07 @ 3:25 am | Permalink
Nee, dat is behoorlijk onwaarschijnlijk juist om de reden die je zelf noemt. Dat zou veel te veel problemen opleveren. Ik heb hier zelf verder ook niks over gehoord.
Wat wel het geval is, is dat de onderliggende library die babbelt met MySQL mogelijk vervangen wordt door mysqlng, een PHP-specifieke implementatie van libmysqlclient. Misschien dat iemand uit deze informatie verkeerde conclusies heeft getrokken.
Het is overigens wel zo dat er inmiddels betere extensies zijn dan de MySQL extensie. Zo is er in PHP5 PDO en MySQLi. Het is, als je inmiddels PHP5 gebruikt, zeker de moeite waard om daar eens naar te kijken.
Over MySQLi heb ik al eens het een en ander geschreven: http://www.scriptorama.nl/databases/een-blik-op-mysqli-deel-i
Door Mathieu Kooiman
op 12.13.07 @ 8:02 am | Permalink
Dank je wel Mathieu, ik ging ervanuit dat het niet zo zou zijn maar ik ben schijnbaar slecht op de hoogte (punt van aandacht voor mezelf) qua PHP evolutie.
Op naar de blik op mysqli.
Door Ray
op 12.13.07 @ 4:24 pm | Permalink
Ik heb ook gehoord dat mysql_qeury() zou verdwijnen. In elk geval ik ben net van start gegaan met het bouwen van men forum en ik ga voor alle zekerheid maar direct gebruik maken van PDO, dan ben ik zeker en het is ook nog eens veiliger.
Door Esli
op 05.02.08 @ 10:04 pm | Permalink
Ik moet zeggen dat de unicode ondersteuning een hele verademing is. Om goed te kunnen testen met verschillende PHP versies, heb ik een systeem opgezet waarmee je vier verschillende PHP versies naast elkaar kan testen. Handig als de code zowel in PHP 5 als PHP 6 moet werken. Kijk op http://www.frajaweb.nl als je meer wil weten.
Door FraJa WeB
op 07.22.08 @ 1:51 pm | Permalink
[...] aangegeven dat het volgens hun beter is om deze functionaliteit, als het geaccepteerd wordt, naar PHP6 door te schuiven, zodat deze buiten Unicode ook nog nieuwe functionaliteit kan bieden. Print [...]
Door PHP 5.3: Closures & Lambda functies | Scriptorama.nl op 08.03.08 @ 1:09 pm | Permalink
PHP6 Krijgt ook namespaces :D
Door Wave6 Webdevelopment
op 01.15.10 @ 4:32 pm | Permalink
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>