Von PHP 7.2 zu PHP 8.1: Wie wir diese Herausforderung meistern
Wir wollten unsere PHP Version von 7.2 auf 8.1 umstellen und haben es einfach gemacht. Na gut, so einfach war und ist es vielleicht nicht, sonst wäre dieser Artikel an dieser Stelle wohl zu Ende.
Wir wollten unsere PHP Version von 7.2 auf 8.1 umstellen und haben es einfach gemacht. Na gut, so einfach war und ist es vielleicht nicht, sonst wäre dieser Artikel an dieser Stelle wohl zu Ende.
Fangen wir einmal von vorne an
Warum machen wir uns überhaupt die Arbeit, unsere PHP Version umzustellen? Warum nutzen wir die knappe Arbeitszeit unserer Entwickler für eine Umstellung, die dem Endnutzer augenscheinlich keinen Vorteil bringt? Weil das eben nur augenscheinlich der Fall ist.
PHP 7.2 ist seit Ende 2020 im Status End of Life, erhält also keine Updates mehr, keine Fehlerkorrekturen, keine Security Patches – und ja, auch eine Programmiersprache wie PHP kann Fehler und Sicherheitslücken haben. Außerdem zwingt uns die Nutzung einer veralteten Version an dieser Stelle leider auch an anderen Stellen dazu, alte Versionen zu nutzen. Dort bekommen wir dann ebenfalls keine Updates mehr, beispielsweise bei eingebundenen Composer-Packages, Ubuntu, usw. Und das letzte Argument pro Umstellung: Neue Versionen bringen in der Regel tolle neue Features mit, die wir natürlich nutzen möchten! Dadurch macht es mehr Spaß zu entwickeln und mit etwas Glück können wir auch einige Optimierungen machen, die der Endnutzer dann eben doch merkt.
Also: Wir wollen PHP 8.1!
Die Herausforderung
Aus den bisherigen Umstellungen wissen wir, dass eine PHP Umstellung gar nicht mal so einfach ist. Meist ist es ein langwieriger Prozess, weil viele Dinge beachtet werden müssen. Außerdem müssen hier echte Profis ran: Sehr erfahrene Entwickler, die genau wissen, wie PHP in seinen Tiefen funktioniert, die unsere Software von vorne bis hinten kennen und abschätzen können, welche Änderungen uns überhaupt betreffen.
Früher übernahm diese Aufgabe oft ein einziger Entwickler, der erfahrenste von allen. Damit hat die Umstellung zeitlich natürlich sehr lange gedauert, was wiederum andere Schwierigkeiten mit sich brachte. Beispielsweise muss es möglich sein, die Software sowohl mit der alten als auch der neuen PHP Version zu betreiben und das komfortabel – sowohl auf unseren Servern als auch lokal für unsere Entwickler. Je länger diese Übergangsphase dauert, desto einfacher müssen die Abläufe gestaltet sein, damit wir auch kontinuierlich weiter arbeiten können. Aber die wohl größte Herausforderung bei dieser Umstellung war der Versionswechsel zwischen 7 und 8. Solche Versionswechsel bringen meistens „Breaking Changes” mit sich, also Änderungen, mit denen der bisherige Code nicht oder falsch läuft. Da einige Stellen in unserem Code seit der ersten onOffice enterprise Version bestehen, löste diese Tatsache natürlich schon leichtes Unbehagen bei uns aus. Vor allem die Verhaltensänderung beim Vergleich inkompatibler Typen, siehe nachfolgende Tabelle, die man kaum statisch prüfen kann, hat uns beunruhigt.
Bei einer einfachen Suche nach dem ==
Operator hatten wir alleine um die 10.000 Treffer. Wie sollten wir alle Operatoren in absehbarer Zeit finden, das gewünschte Verhalten herausfinden und dann fixen? Eine echte Sisyphusarbeit! Und das war nicht alles: Hinzu kommt hier noch jeder Vergleich mit >
, <
, >=
, <=
, !=
, sowie die indirekte Nutzung dieser Operatoren in array_search
, etc. Somit eine unlösbare Aufgabe! Oder doch nicht?
Die Lösung
Zunächst haben wir uns dieses Mal der Aufgabe mit einem ganzen Team gewidmet – fünf Entwickler vs. vier Versionssprünge. Durch die Diskussionen, wie die Herausforderungen am besten bewältigt werden könnten, haben wir für uns sehr gute Lösungen gefunden.
Für den parallelen Betrieb haben wir die Entwickler bereits auf Version 8.1 umgestellt. So wurden beim lokalen Testen bereits Fehler aufgedeckt, die unter 8.1 auftreten, aber vielleicht nicht von einem Test abgedeckt sind. Wenn wir den Fehler allerdings nicht schnell beheben konnten, sollte das Arbeiten weiterhin möglich sein. Also gibt es einen ganz einfachen Switch, um wieder auf Version 7.2 wechseln zu können. Somit stellten wir sicher, dass der neue Code auf jeden Fall unter 8.1 lauffähig ist. Die Kompatibilität zu 7.2 wurde durch unsere Tests auf dem Testserver abgedeckt. Neuer Code musste auf jeden Fall getestet werden, folglich sind Verhaltensänderungen hier sofort aufgefallen.
Nun zu unserer größten Herausforderung: Der Breaking Change wie oben beschrieben. Da wir nicht alle Codestellen korrigieren konnten, zumindest nicht in akzeptabler Zeit mit fünf Entwicklern, mussten wir eine temporäre Lösung finden, die nach und nach von allen gemeinsam wieder ausgebaut werden kann. Also haben wir alle Funktionen, die ihr Verhalten ändern, nachgebaut, sodass sie das aktuelle Verhalten widerspiegeln. Diese haben wir dann mit Hilfe von Rector in unserem kompletten Code verbaut. Dann haben wir natürlich noch alles mit Tests abgedeckt und schließlich einige Zeit durch den Produktivbetrieb prüfen lassen. In dieser Zeit haben die Funktionen immer das native Ergebnis zurückgegeben, uns aber Fehlermeldungen geschickt, falls unser berechnetes Ergebnis vom nativen Ergebnis unter 7.2 abweicht. So konnten wir noch einige Fehler entdecken, den Test erweitern und natürlich die Funktionen korrigieren.
Wie es weitergeht
Nun kommt Phase 2: Einige Server werden auf Version 8.1 umgestellt. Unsere Funktionen geben weiterhin denselben Wert wie unter 7.2 aus. Gleichzeitig wird dieser Wert jedoch gegen das native 8.1 Ergebnis geprüft und Unterschiede an uns gemeldet. So finden wir mit der Zeit alle potentiell gefährlichen Stellen und können diese markieren. Nach einigen Monaten können wir nun unsere Funktionen wieder zurückbauen, bis auf die markierten Stellen, und können uns sicher sein, dass alles weiterhin wie bisher funktioniert. Die markierten Stellen können nun nach und nach durch Entwickler, die sowieso gerade Änderungen an dieser Stelle durchführen, geprüft und ausgebaut werden.
Das Zwischenergebnis
Am Ende nutzen wir 8.1 und es gibt keine Verhaltensänderungen in der Software. Was will man mehr? In einem unserer nächsten Beiträge melden wir uns mit einem kleinen DeepDive in unsere PHP Umstellung und die technischen Feinheiten zurück.