PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


PHP 7: Migration eines Projekts

with 9 comments

PHP 7Noch 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.

uniform_variable_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.

Written by Michael Kliewe

Oktober 24th, 2015 at 6:30 pm

Posted in PHP

Tagged with , , , , , ,

9 Responses to 'PHP 7: Migration eines Projekts'

Subscribe to comments with RSS or TrackBack to 'PHP 7: Migration eines Projekts'.

  1. Spannender Beitrag! *daumen hoch*

    Peter

    27 Okt 15 at 17:20

  2. Cool cool.

    Ich hoffe ihr habt auch eine Strategie für die Umstellung eurer App auf ZF2 in der Schublade 😉 PHP 7.x wird sonst irgendwann nicht laufen.

    Fab

    27 Okt 15 at 23:35

  3. @Fab: Ja, das wird eine interessante Frage. Aber erstens glaube ich nicht dass PHP 7.x so große Backwards-Compatibility-Brüche einbauen wird sodass ZF1 nicht mehr läuft, und zweitens soll ja bald auch ZF3 erscheinen (eigentlich war Q3 2015 der Plan laut Roadmap aus Januar), also wird man wahrscheinlich ZF2 überspringen. Mal sehen, das wird ein ziemlich großes Refactoring werden, vielleicht kommt auch ein Wechsel auf Symfony in Frage, mal schauen wie es nächstes Jahr aussieht.

    http://framework.zend.com/blog/announcing-the-zend-framework-3-roadmap.html

    Michael Kliewe

    27 Okt 15 at 23:48

  4. […] In knapp zwei Wochen erscheint PHP 7! Bereits jetzt setzen sich einige User mit der neuen Version auseinander und teilen ihre Erfahrungen. So empfiehlt Michael Kliewe jedem, seinen Code vor der Umstellung auf PHP 7 mit Hilfe automatischer Tools analysieren zu lassen. Warum das für die Migration wichtig ist, erfahrt ihr im dazugehörigen Artikel. […]

  5. Der Einsatz von PHP 7 wird auf jeden Fall einiges bringen. Alleine schon der geringere RAM Verbrauch und die dadurch höhere Performance werden einige Webseite ein längeres Leben schenken :)

    Zudem wird es auch so sein, dass PHP 7 eine etwas größere Hürde für den ein oder anderen Entwickler geben wird, der gerade damit anfangen will sich mit Software Entwicklung auseinander zu setzen.

    Ich glaube aber alles in allem, ist die neue Version sinnvoll und eine Migration darauf immer anzuraten!

  6. Hallo

    sagmal, kann ich Memcached auch für PHP7 unter LAMPP bereitstellen? Wenn ja, wie geht das?

    ich

    7 Mrz 16 at 13:40

  7. @ich: Ich verstehe deine Frage leider nicht. Funktioniert die Vorgehensweise, wie oben beschrieben unter „memcached Extension“, nicht? So habe ich es auf einem Ubuntu Server kompiliert für PHP7.

    Michael Kliewe

    7 Mrz 16 at 13:44

  8. na ja, ich habe LAMPP installiert und versuche nun, für diese Entwicklungsumgebung Memcached bereit zu stellen, es scheint aber immer wieder zu Fehlern zu kommen.

    Ich will ja LAMPP/XAMPP behalten weils für mich übersichtlicher ist. Man sagte mir, dass das möglich wäre wenn ich auf LAMPP/XAMPP verzichten würde.

    ich

    8 Mrz 16 at 22:59

  9. Der Geschwindigkeitsunterschied ist spürbar. In Peakzeiten hält der Server deutlich mehr PHP-Requests (Mindestens 30%) aus, was wahrscheinlich mit dem geringerem Arbeitspeicherverbrauch zusammen hängt.

    Patrick Schinkel

    1 Jun 16 at 17:48

Leave a Reply

You can add images to your comment by clicking here.