| 

.NET C# Java Javascript Exception

8
Noch knapp einen Monat warten, dann erscheint das Christkind PHP7! Was gibt es also schöneres als sich damit zu beschäftigen und erste Erfahrungen zu sammeln? Im Januar habe ich mir speziell den Arbeitsspeicherverbrauch von PHP 7 angeschaut, die ChangeLogs verinnerlicht, es kompiliert und ein paar Testzeilen ausgeführt. Das lief schon sehr gut, aber um größere […]

Noch knapp einen Monat warten, dann erscheint das Christkind PHP7! Was gibt es also schöneres als sich damit zu beschäftigen und erste Erfahrungen zu sammeln?

Im Januar habe ich mir speziell den Arbeitsspeicherverbrauch von PHP 7 angeschaut, die ChangeLogs verinnerlicht, es kompiliert und ein paar Testzeilen ausgeführt. Das lief schon sehr gut, aber um größere Projekte laufen zu lassen mangelte es noch an einigen Extensions. Außerdem wollte ich ein Zend Framework 1 Projekt testen, und ZF1 war zu dem Zeitpunkt noch nicht PHP 7-kompatibel.

Doch das hat sich geändert. ZF1 ist seit Mai 2015 mit Version 1.12.12 PHP 7 kompatibel, und auch die von mir benötigten Extensions wurden umgebaut, sodass es nun PHP 7-kompatible Branches vieler Extensions auf Github gibt.

Die Vorgehendweise: Neueste PHP 7 Version herunterladen, kompilieren, Extensions herunterladen, kompilieren, und dann SPASS HABEN!

Also los! PHP 7 RC5 kompilieren

wget https://downloads.php.net/~ab/php-7.0.0RC5.tar.gz
tar -xzvf php-7.0.0RC5.tar.gz
cd php-7.0.0RC5/
./configure --prefix=/usr/local/php7.0.0RC5 --with-zlib --with-config-file-path=/usr/local/php7.0.0RC5/etc --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-zip --with-imap --with-kerberos --with-imap-ssl --with-openssl --with-jpeg-dir --with-gd --with-gettext --with-freetype-dir --enable-ftp --with-pspell --with-curl
make
make test
sudo make install
/usr/local/php7.0.0RC5/bin/php -v
/usr/local/php7.0.0RC5/bin/php -m
/usr/local/php7.0.0RC5/bin/php -i

Funktioniert wunderbar! Weiter gehts.

Extensions memcached, gearman und apcu

Diese 3 Extensions benötige ich für das Projekt. Laut GoPHP7 extensions Catalog sind sie für PHP 7 verfügbar, dann mal „Go“!

memcached Extension:

git clone https://github.com/php-memcached-dev/php-memcached.git --branch php7
cd php-memcached/
/usr/local/php7.0.0RC5/bin/phpize --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
./configure --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
make
make test
sudo cp modules/* /usr/local/php7.0.0RC5/lib/php/extensions/no-debug-non-zts-20151012/
sudo nano /usr/local/php7.0.0RC5/etc/php.ini
 extension=memcached.so
/usr/local/php7.0.0RC5/bin/php -m

gearman Extension:

git clone https://github.com/wcgallego/pecl-gearman.git
cd pecl-gearman/
/usr/local/php7.0.0RC5/bin/phpize --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
./configure --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
make
make test
sudo cp modules/* /usr/local/php7.0.0RC5/lib/php/extensions/no-debug-non-zts-20151012/
sudo nano /usr/local/php7.0.0RC5/etc/php.ini
 extension=gearman.so
/usr/local/php7.0.0RC5/bin/php -m

apcu Extension:

git clone https://github.com/krakjoe/apcu.git --branch seven
cd apcu
/usr/local/php7.0.0RC5/bin/phpize --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
./configure --enable-apcu-bc --with-php-config=/usr/local/php7.0.0RC5/bin/php-config
make
make test
sudo cp modules/* /usr/local/php7.0.0RC5/lib/php/extensions/no-debug-non-zts-20151012/
sudo nano /usr/local/php7.0.0RC5/etc/php.ini
 extension=apcu.so
 extension=apc.so
 apc.enabled=1
 apc.shm_size=256M
 apc.ttl=7200
 apc.enable_cli=1
 apc.gc_ttl=3600
 apc.entries_hint=4096
 apc.slam_defense=1
 apc.serializer=php
/usr/local/php7.0.0RC5/bin/php -m
/usr/local/php7.0.0RC5/bin/php -r "echo apc_store('a', 'b');"

Im Unterschied zu früher gibt es nun zwei Extensions: apcu.so und apc.so. Man muss beide laden, dann funktionieren die „alten“ apc_* Funktionen (apc_fetch(), apc_store()…) wieder. Lädt man nur apcu.so, dann kann man nur apcu_fetch(), apcu_store() usw. nutzen. Abwärtskompatible Projekte brauchen die alten apc_* Funktionen. Lädt man nur die neue apc.so, dann erhält man die Fehlermeldung „Unable to load dynamic library: … undefined symbol: zif_apcu_store“. Lädt man beide funktioniert alles. An dieser Hürde bin ich etwas hängengeblieben…

Migrationsvorbereitungen

Ich hatte es mir schon vor 2 Monaten mal angeschaut, aber jetzt nochmal frisch: Mit Hilfe des PHP Migration Assistant PHP 7 Migration Assistant Report(MAR) mein Projekt analysiert und geschaut welche Probleme auftreten.

Es zeigte mir eine Menge Hinweise zu „funcGetArg“ (also Benutzungen von func_get_args()) an. In der aktuellen Version des PHP 7 Migration-Guides steht zu dem Thema nichts, aber es scheint so zu sein dass früher func_get_args() immer die Originalwerte der Funktionsparameter geliefert hat. Werden die Werte also VOR dem func_get_args() Aufruf verändert, so erhielt man die alten Werte. Seit PHP 7 erhält man die veränderten Werte. Da an den von php7mar bemängelten Stellen die Variablen nicht verändert wurden vor dem Aufruf sind es also alles False-Positives und damit kein Problem.

Danach kamen noch einige kritische Hinweise zu „variableInterpolation“, dies sind ernst zu nehmende Stellen die in PHP 7 zu Bugs führen. Es geht um die Änderungen bzgl. der Uniform Variablen Syntax.

Mit ein paar geschweiften Klammern an den richtigen Stellen waren die Probleme gelöst.

Dies ist meiner Meinung nach das gefährlichste Backwards-Compatibility-Problem in PHP 7: Es gibt keinerlei Deprecated Warnung, keinerlei Syntax Fehler oder ähnlich. Es ändert sich still und heimlich die Syntax, und Code der seit Jahren funktioniert hat funktioniert nun nicht mehr so wie früher. In den meisten Fällen sollte es in „Undefined Index“ oder „xxx is not a function“ münden und damit leicht zu finden und zu beheben sein, aber in Produktionsumgebungen kann es deshalb zu komischem Verhalten bis hin zu Datenverlust führen…

Insgesamt befanden sich 90% der gefundenen Hinweise in Fremdbibliotheken, nur 10 Hinweise betrafen „meinen“ Code. Es ging also auch etwas Zeit ins Land den anderen Entwicklern Bescheid zu geben, bei GitHub Issues zu eröffnen bzw. Pull-Requests zu erstellen.

(Nette Nebeninfo: Führe ich php7mar mit dem „alten“ PHP 5.6 aus, dann dauert die Code-Analyse 225 Sekunden. Mit PHP 7 nur noch 66 Sekunden! Yeah, das rockt!)

Unit-Tests laufen lassen

Nachdem ich die angezeigten Probleme behoben habe (auch hauptsächlich in externen Bibliotheken wie dompdf oder einer recht alten PEAR-Klasse, die noch PHP4-Konstruktoren hatte), konnte ich mich dran machen und die Unit-Tests laufen lassen. Und was soll ich sagen: KEINE FEHLER! Ich habe also das gute Gefühl dass ich keine großen Probleme bei der Umstellung haben werde.

Time: 2.52 minutes, Memory: 156.00Mb
Time: 3.32 minutes, Memory: 235.25Mb

Ihr dürft raten welcher der beiden Unit-Test-Runs PHP 5.6 und und welcher PHP 7 ist

Interessant fand ich dass auch PHPUnit 4.6.6 funktionierte, ich hätte erwartet dass ich für PHP 7 auch die PHP 7 kompatible PHPUnit 5.0 hätte verwenden müssen. Dem war nicht so, ein Update liegt aber trotzdem nahe.

Die nächsten Schritte werden sein die Entwickler-Rechner und die Staging-Umgebung mit PHP 7 auszurüsten, sodass mehr Erfahrungen gesammelt werden, und Bugs durch die manuelle Benutzung der Applikation gesucht werden, die evtl. nicht von Unit-Tests abgedeckt sind, oder die nur in Verbindung mit einem echten Browser oder Webserver wie Apache oder PHP-FPM auftreten… Wer weiß…

Migrationsempfehlungen

Ich kann jedem nur empfehlen seinen Code vor der Umstellung auf PHP 7 mit Hilfe automatischer Tools analysieren zu lassen, um genau solche Probleme zu finden. Neben php7mar gibt es noch andere Migrations-Tools wie beispielsweise php7cc oder phan (findet glaube ich „nur“ die Uniform Variable Syntax Probleme?). Am besten alle durchlaufen lassen.

Und ganz wichtig: Den PHP 7 Migration-Guide komplett durchlesen. Je nach Größe des Projektes ist es außerdem keine schlechte Idee, erstmal nur einzelne Nutzer oder nur 1% des Traffics auf PHP 7 zu leiten, und bei Problemen schnell wieder umschalten zu können auf PHP 5.6… Ist zwar etwas mehr Aufwand, man hat aber nicht mehr so viel Angst vor der Umstellung eines größeren Projekts.

php gearman php-7 apcu memcached php7 php7mar php-7-migration
Schreibe einen Kommentar:
Themen:
php-7-migration php7mar php7 memcached apcu php-7 gearman php
Entweder einloggen... ...oder ohne Wartezeit registrieren
Benutzername
Passwort
Passwort wiederholen
E-Mail