Das Bild zeigt eine symbolträchtige Szene, die Zusammenarbeit und Teamgeist symbolisiert. Im Mittelpunkt stehen mehrere Hände, die von oben in einem Kreis angeordnet sind und gemeinsam hölzerne Puzzleteile zueinander führen. Die Hände stammen von verschiedenen Personen, die unterschiedliche Kleidung tragen. Teilweise sind helle Hemden und graue Ärmel erkennbar. Das Szenario spielt sich auf einer grünen Wiese ab, was Natürlichkeit und Offenheit vermittelt. Die hellen Puzzleteile repräsentieren die einzelnen Komponenten, die zusammengesetzt werden müssen, um ein großes Ganzes zu bilden.

Das PHP-Ökosystem ist ein echtes Paradebeispiel für kollaborative Softwareentwicklung, bei dem die PHP-Laufzeitumgebung und wichtige Bibliotheken sich gegenseitig durch eine automatisierte Testinfrastruktur unterstützen.

Diese gegenseitige Hilfe zeigt sich in zwei nächtlichen Continuous Integration-Workflows: Das PHP-Projekt testet die Auswirkung von Änderungen an PHP auf wichtige Ökosystemkomponenten, während PHPUnit sich selbst auch mit Entwicklungsversionen von PHP testet und so ein Sicherheitsnetz schafft, von dem die ganze Community profitiert.

Denn nur, wenn PHPUnit mit den aktuellen Entwicklungsversionen von PHP kompatibel ist, können andere kritische Projekte des PHP-Ökosystems wie Composer oder PHPStan überprüfen, ob sie ebenfalls kompatibel sind. PHPUnit fungiert dabei als eine Art Brücke, die Änderungen in der Programmiersprache und der Laufzeitumgebung unmittelbar für das gesamte Ökosystem zugänglich macht. Solange PHPUnit kompatibel bleibt, können andere Tools und Frameworks ihre eigenen Test-Suites gegen die neuen PHP-Versionen ausführen, noch bevor diese offiziell veröffentlicht werden.

Auf diese Weise entstehen mehrschichtige Sicherheitsnetze. Während PHP selbst die Kompatibilität mit wichtigen Bibliotheken überprüft, validieren diese Bibliotheken gleichzeitig die Stabilität von PHP. Diese gegenseitige Abhängigkeit verwandelt potenzielle Breaking Changes in Chancen für frühzeitiges Feedback und kontinuierliche Verbesserung, sodass die gesamte Community von robusteren PHP-Versionen profitiert.

Testen als eine Art der Zusammenarbeit im Ökosystem

Im Mittelpunkt dieser Zusammenarbeit steht der nächtliche Continuous Integration-Workflow (CI) des PHP-Projekts, der umfassende Testsuiten für sieben wichtige Ökosystemprojekte durchführt: AMPHP, Laravel, ReactPHP, Revolt PHP, Symfony, PHPUnit und WordPress. Dabei geht es nicht nur um die Qualitätssicherung für PHP selbst, sondern um ein proaktives Engagement für die Gesundheit des Ökosystems.

Durch das nächtliche Testen dieser Projekte mit den neuesten Entwicklungsversionen von PHP kann das PHP-Projekt kritische Änderungen erkennen, bevor sie in die Produktion gelangen, und so den Entwicklerinnen und Entwicklern wichtiger Ökosystemprojekte frühzeitig Bescheid geben, damit sie ihren Code anpassen können.

Das oben Genannte ergänzt die eigene Testsuite von PHP, die auf mehreren Plattformen ausgeführt wird, darunter Linux (X64/X86-32/PPC64), macOS (X64/ARM64), FreeBSD und Windows, mit verschiedenen Konfigurationen wie Debug-Builds, threadsicheren und nicht threadsicheren Versionen sowie compiler-gestützten Testverfahren wie AddressSanitizer (ASAN) und UndefinedBehaviorSanitizer (UBSAN).

ASAN und UBSAN sind runtime-basierte Test Oracles, die durch Compile-Zeit-Instrumentation während der Testausführung aktiv werden. Sie transformieren ansonsten stumme Fehler wie Buffer Overflows, Use-After-Free, Heap Leaks oder Fehler, die durch undefiniertes Verhalten gemäß dem C/C++ Standard entstehen, in beobachtbare Fehler. Damit liefern sie automatische Urteile zur Korrektheit des getesteten Codes.

Die Ökosystem-Testinfrastruktur checkt auch, ob der Bytecode-Optimierer des PHP-Compilers korrekt funktioniert. Dessen Optimierungspipeline nutzt statische Typinferenz, um die Datentypen der Operanden aus dem Bytecode zu bestimmen. Das ermöglicht Optimierungen wie das Entfernen unnötiger FREE-Opcodes, wenn eine temporäre Variable eindeutig als ein bestimmter Typ identifiziert wird, zum Beispiel long. Fehler in dieser Inferenzlogik können jedoch zu subtilen, aber kritischen Bugs führen.

Um das zu vermeiden, wird das Flag ZEND_VERIFY_TYPE_INFERENCE in PHP für den nächtlichen CI-Workflow aktiviert, in dem wichtige Ökosystemprojekte getestet werden. Dieses Flag aktiviert eine tiefgreifende Instrumentierung innerhalb des Bytecode-Executors, die die tatsächlichen Operanden fast aller Opcodes während der Laufzeit mit ihren statisch abgeleiteten Typen vergleicht. Jede Abweichung löst sofort einen Fehler aus, wodurch sichergestellt wird, dass komplexe Optimierungsfehler erkannt und behoben werden, bevor sie sich auf das gesamte Ökosystem auswirken können.

PHPUnits gegenseitige Wachsamkeit

Für PHPUnit habe ich einen CI-Workflow mit der umgekehrten Perspektive. Alle Codeänderungen, die in einen Branch von PHPUnit gepusht werden, werden mit der PHPUnit-eigenen Testsuite für alle PHP-Versionen getestet, die dieser Branch unterstützt. Dazu gehören natürlich auch die Entwicklungsversionen von PHP. Außerdem läuft ein nächtlicher CI-Workflow, der die PHPUnit-Testsuite für alle unterstützten Branches von PHPUnit mit den PHP-Versionen testet, die jeder dieser Branches unterstützt.

Sobald die Entwicklung der PHP-Version beginnt, die nach der nächsten PHP-Version veröffentlicht wird, fange ich an, in den CI-Workflows für PHPUnit gegen diese PHP-Version zu testen. Zum Beispiel hat die Entwicklung von PHP 8.6 am 23. September 2025 begonnen, ungefähr zwei Monate vor der Veröffentlichung der ersten stabilen Version von PHP 8.5 am 20. November 2025. Seit dem 26. September 2025 werden alle Änderungen, die an einen der PHPUnit Branches gepusht werden, auch mit PHP 8.6 getestet.

Dadurch kann ich erkennen, wann PHP Änderungen einführt, die sich auf das Test-Framework auswirken, und so sicherstellen, dass PHPUnit sowohl mit stabilen als auch mit kommenden PHP-Versionen kompatibel bleibt. Diese bidirektionale Prüfung schafft eine Feedbackschleife, die für beide Projekte und damit auch für die Millionen von Entwicklerinnen und Entwicklern, die sich auf sie verlassen, von Vorteil ist.

Möglich wird dies nicht zuletzt durch Shivam Mathurs setup-php, das eine umfassende Plattformabstraktion für Linux, macOS und Windows sowie Binärdateien für die PHP-Laufzeitumgebung von PHP 5.3 bis, zum Zeitpunkt der Erstellung dieses Artikels, zu den Nightly Builds von PHP 8.6 bietet.

Die technische Architektur der gegenseitigen Unterstützung

Der Nightly Workflow des PHP-Projekts zeigt, dass die Bedürfnisse des Ökosystems gut verstanden werden. Für jedes getestete Projekt macht er Folgendes:

  • Klont die neueste Repository-Version
  • Installiert Abhängigkeiten mit Composer
  • Richtet passende Testumgebungen wie Datenbanken ein
  • Führt projektspezifische Testbefehle aus
  • Meldet Fehler, die auf PHP-Kompatibilitätsprobleme hindeuten könnten

Wenn zum Beispiel Symfony getestet wird, so muss der Nightly Workflow des PHP-Projekts durch die Monorepo-Struktur navigieren und jede Komponente einzeln testen, wobei er die gegenseitigen Abhängigkeiten berücksichtigt. Das Testen von WordPress umfasst die Konfiguration von wp-tests-config.php mit Datenbank-Anmeldedaten und die Ausführung von PHPUnit für die WordPress-Testsuite.

Dieser Integrationsgrad erfordert eine kontinuierliche Wartung. Da Projekte ihre Testinfrastruktur weiterentwickeln, muss das PHP-Projekt seine Workflows aktualisieren, um Änderungen bei Testbefehlen, Abhängigkeitsanforderungen und der Konfiguration der Umgebung Rechnung zu tragen. Das Engagement für diese Wartung unterstreicht, wie ernst das PHP-Projekt die Stabilität des Ökosystems nimmt.

Ergänzend zu diesen Upstream-Anstrengungen nutzt Remi Collet seine Rolle bei Red Hat, um sicherzustellen, dass der PHP-Interpreter sowie Bibliotheken und PHP-basierte Anwendungen innerhalb des breiteren Linux-Distributionsökosystems paketierbar und funktionsfähig sind. Seine Arbeit erstreckt sich auch auf die Zukunft, indem er Build-Sammlungen für kommende Fedora-Versionen pflegt. Durch die Bereitstellung von Entwicklungsversionen als RPM-Pakete und deren Testen mit Systembibliotheken auf Architekturen wie X64, ARM64, PPC64 und S390X fungiert der Build-Server von Fedora als abschließender Integrationstest auf Systemebene. Dadurch werden Binärinkompatibilitäten und Paketierungsprobleme erkannt, die in reinen CI-Umgebungen auf Codeebene möglicherweise übersehen werden, und so lange vor dem offiziellen Veröffentlichungsdatum effektiv die Voraussetzungen für die endgültige Einführung von PHP in Fedora und RHEL geschaffen.

Vorteile über die Fehlererkennung hinaus

Die gegenseitige Testinfrastruktur hat Vorteile, die über das Finden von Fehlern hinausgehen:

Frühwarnsystem: Die Projektverantwortlichen werden schon früh über wichtige Änderungen informiert, oft Monate bevor PHP-Versionen in Produktion gehen. Diese Vorlaufzeit ermöglicht eine schrittweise Anpassung, anstatt nach der Veröffentlichung schnell Fixes machen zu müssen.

Vertrauen in die Weiterentwicklung: Das PHP-Projekt kann Sprachänderungen mit mehr Zuversicht durchführen, weil es weiß, dass die Auswirkungen auf das Ökosystem schnell sichtbar werden. Das beschleunigt Innovationen und sorgt gleichzeitig für Stabilität.

Weniger Fragmentierung: Die Koordination von Tests auf einer gemeinsamen Infrastruktur verhindert die Fragmentierung des Ökosystems, die auftritt, wenn verschiedene Projekte unterschiedliche Annahmen über das Verhalten von PHP treffen.

Vertrauen der Community: Das sichtbare Engagement für das Testen von kritischen Ökosystemprojekten schafft Vertrauen. Entwicklerinnen und Entwickler können sehen, dass die Entwicklung von PHP unter ausdrücklicher Berücksichtigung der realen Nutzung erfolgt und nicht isoliert stattfindet.

Effizienz durch Automatisierung: Wie Martin Fowler in Bezug auf kontinuierliche Integration feststellt, reduzieren automatisierte Builds und Tests das Risiko von Verzögerungen und fördern Praktiken, die zu einer gesunden Codebasis beitragen. Das PHP-Ökosystem veranschaulicht dieses Prinzip in großem Maßstab.

Herausforderungen

Diese Testbeziehungen aufrechtzuerhalten, ist nicht ganz einfach. Der Nightly Workflow von PHP deaktiviert manchmal bestimmte Tests, zum Beispiel werden momentan Symfonys HtmlSanitizerCustomTest und FFICasterTest wegen bekannter Probleme übersprungen. Diese pragmatischen Entscheidungen verhindern, dass unzuverlässige Tests echte Probleme verschleiern, aber sie sind auch eine technische Belastung, die irgendwann gelöst werden muss.

Die Komplexität des Workflows erhöht den Wartungsaufwand. Verschiedene Projekte brauchen unterschiedliche Dienste wie MySQL, PostgreSQL, Firebird usw., verschiedene PHP-Erweiterungen und unterschiedliche Konfigurationsparameter. Der COMMUNITY-Job kümmert sich um ASAN/UBSAN-Builds und braucht spezielle Umgebungsvariablen, um das Verhalten des Sanitisers zu verwalten.

Der Blick nach vorne

Das Modell der gegenseitigen Tests im PHP-Ökosystem ist ein echt gutes Beispiel für andere Communities. Indem sie projektübergreifende Tests über die CI-Infrastruktur zur Standardpraxis gemacht haben, hat die PHP-Community nachhaltige Mechanismen für die Zusammenarbeit geschaffen, die nicht von persönlichen Beziehungen oder Ad-hoc-Kommunikation abhängen.

Während sich PHP mit Features wie verbessertem Typsystem, Leistungsoptimierungen und neuen Sprachkonstrukten weiterentwickelt, wächst die Testinfrastruktur ganz natürlich mit. Ein neues Projekt in den nächtlichen Workflow aufzunehmen, ist einfach, und es gibt schon Beispiele dafür, dass weitere Ökosystemkomponenten hinzugefügt werden, wenn sie wichtiger werden.

Die Zusammenarbeit zwischen PHP und PHPUnit, vermittelt durch eine automatisierte Testinfrastruktur, stellt einen ausgereiften Ansatz für die Open Source-Entwicklung dar. Anstatt die Programmiersprache und ihre Tools als getrennte Bereiche zu behandeln, erkennt die PHP-Community ihre gegenseitige Abhängigkeit an und baut Systeme auf, die beide unterstützen. Diese gegenseitige Investition in Stabilität und Kompatibilität garantiert, dass PHP auch weiterhin eine zuverlässige Grundlage für Millionen von Websites und Anwendungen sein wird, die darauf angewiesen sind.