PHP 7: Skriptsprache kommt in der Gegenwart an
Über 11 Jahre nach der Veröffentlichung von Version 5 hat das PHP-Projekt mit PHP 7.0.0 endlich den großen Release-Sprung vollzogen. Der Druck durch Facebooks Konkurrenztechnik HHVM hat zu etlichen performancerelevanten Überarbeitungen geführt.
- Sebastian Bergmann
- Christian Kirsch
Über 11 Jahre nach der Veröffentlichung von Version 5 hat das PHP-Projekt mit PHP 7.0.0 endlich den großen Release-Sprung vollzogen. Der Druck durch Facebooks Konkurrenztechnik HHVM hat zu etlichen performancerelevanten Überarbeitungen geführt.
Mehr als 180 Entwickler haben an PHP 7 gearbeitet, nur wenige wie Anatol Belski von Microsoft und Dmitry Stogov von Zend bekamen Geld dafĂĽr. In der neuen Version stecken knapp 10.000 Ă„nderungen gegenĂĽber PHP 5.
Warum die heute veröffentlichte Version nicht PHP 6 heißt, ist genau so amüsant wie die Theorien darüber, warum Microsoft Windows 10 nicht Windows 9 genannt hat: Das 2009 veröffentlichte PHP 5.3 hätte eigentlich PHP 6 heißen sollen. Damals war die native Unterstützung für Unicode als Grund für den Versionssprung vorgesehen. Als die Entwickler sie aufgaben, wurde aus PHP 6 eben PHP 5.3. Jedoch hatten einige Verlage Bücher über PHP 6 angekündigt und manche sogar bereits veröffentlicht. Wenn sechs Jahre später ein PHP 6 erscheint, das nichts mit der für 2009 geplanten Version zu tun hat, könnten diese Bücher Entwickler verwirren. Deshalb entfällt Version 6.
Ă„nderungen unter der Haube
Die Arbeit an PHP 7 nahm im Sommer 2014 Fahrt auf, als die Entwicklungen aus dem PHPNG-Branch in den Code einflossen. In diesem Entwicklungszweig hatte Dmitry Stogov den ausführenden Kern von PHP refaktoriert, damit das Programm schneller läuft und weniger Speicherplatz benötigt. Insgesamt nahmen die Entwickler für PHP 7 Hunderte Optimierungen an diesem Kern vor – unter anderem, um von Verbesserungen in aktuellen C-Compilern profitieren, verstärkt CPU-Caches nutzen, Arbeitsspeicher effizienter alloziieren, Hashtables performanter verarbeiten und besseren PHP-Bytecode erzeugen zu können.
In einem Vortrag auf der FrOSCon-Konferenz im August 2015 präsentierte Sprachschöpfer Rasmus Lerdorf zu Beginn der Release-Candidate-Phase von PHP 7.0 einige Benchmarks, welche die Leistungsverbesserungen anschaulich demonstrieren. Beispielsweise kann das neue PHP 80 Prozent mehr Drupal-8-Requests pro Sekunde verarbeiten als PHP 5.6 und 30 Prozent mehr Requests pro Sekunde als die von Facebook entwickelte HipHop Virtual Machine 3.7 (HHVM).
Bei WordPress 4.1.1 zeigen sich die Verbesserungen noch eindrucksvoller: PHP 7.0 verarbeitet mehr als doppelt so viele Anfragen pro Sekunde wie PHP 5.6. Ohne weitere Optimierungen liegt es allerdings bei diesem Wert um 6 Prozent hinter HHVM. Kompiliert man PHP 7.0 jedoch selbst und "trainiert" den PHP-Interpreter unter Verwendung der von GCC unterstĂĽtzten Feedback-Directed Optimization (auch als Profile-Guided Optimization bekannt) auf die AusfĂĽhrung von WordPress, liegen PHP 7.0 und HHVM gleichauf.
Nicht nur bei dem Teil des Kerns von PHP, der Bytecode ausfĂĽhrt, blieb kaum ein Stein auf dem anderen. Viel Arbeit floss auch in die grundlegende Ăśberarbeitung von Lexer, Parser und Bytecode-Generator. Der PHP-Lexer ist nun kontextsensitiv) und unterstĂĽtzt semireservierte SchlĂĽsselworte. Das erlaubt die Nutzung der meisten SchlĂĽsselworte als Namen von Attributen, Konstanten und Methoden in Klassen, Interfaces und Traits. Die einzige Ausnahme ist class, das weiterhin nicht an diesen Stellen auftauchen darf. Als Namen von Klassen, Interfaces und Traits sind SchlĂĽsselworte weiterhin verboten.
Statt direkt aus dem Parser heraus Bytecode zu erzeugen, wird nun zunächst ein abstrakter Syntaxbaum erstellt. Er bildet die Grundlage für das Erzeugen von Bytecode und steht darüber hinaus über APIs wie php-ast von Nikita Popov oder Sara Golemons astkit zur Verfügung. Mit ihrer Hilfe lassen sich beispielsweise in PHP selbst effizient Werkzeuge für die statische Codeanalyse von PHP-Code erstellen. Ferner entspricht die Verwendung eines abstrakten Syntaxbaums im Parser eher dem Status quo in der Implementierung von Compilern als das, was an dieser Stelle bislang in PHP geschah. Dieses Refactoring des Parsers macht Änderungen an der PHP-Syntax nicht nur einfacher, sondern auch risikoärmer. Darüber hinaus wird es in Zukunft für Entwickler, die neu zum PHP-Projekt hinzustoßen, deutlich einfacher sein als bisher, sich in die Arbeitsweise des Compilers einzuarbeiten.
Migration & Umstieg
Was man bei der Migration beachten muss
Die Änderungen am kompilierenden und ausführenden Kern von PHP alleine wären schon Grund genug für den Versionsnummernsprung. Das PHP-Projekt hat die Gelegenheit jedoch gleichzeitig genutzt, um etliche zuvor als "deprecated" markierte Altlasten aus PHP zu entfernen sowie inkonsistente und undokumentierte Semantik aufzuräumen. Nicht zuletzt um die saubere Implementierung eines abstrakten Syntaxbaums zu ermöglichen, überarbeiteten die Entwickler daher die Syntax bezüglich der Verwendung von Variablen.
Konstrukte wie $$foo['bar']['baz'], die man aufgrund ihrer Unlesbarkeit ohnehin nicht
verwenden möchte, haben nun eine eindeutige Semantik. Im konkreten Fall hat sich diese von
${$foo['bar']['baz']} zu ($$foo)['bar']['baz'] geändert. Da die Syntax allerdings unverändert bleibt, erzeugt der PHP-Interpreter beim Laden dieses Codes keinen Syntaxfehler. Stattdessen kann es zu Laufzeitfehlern kommen, weil der Code nun eine andere Bedeutung hat als vorher. Ein Werkzeug wie der PHP Analyzer phan findet allerdings durch statische Codeanalyse ausgehend vom neuen abstrakten Syntaxbaum all die Stellen, wo sich aufgrund der Uniform-Variable-Syntax die Semantik von Variablenzugriffen geändert hat.
Im Zuge der Überarbeitung sind neue Schlüsselwörter hinzugekommen. Dazu gehören die Namen von Datentypen wie int, bool und string sowie die Konstanten true, false und null. PHP 7 reseviert außerdem Begriffe wie resource und object. Auch für diese Schlüsselwörter gilt die oben beschriebene Erleichterung: Sie sind lediglich als Namen für Klassen, Interfaces und Traits verboten, können jedoch beispielsweise innerhalb von Klassen als Bezeichner für Attribute auftauchen.
Seit seiner frühesten Jugend hatte PHP eine besonders enge Beziehung zu der freien SQL-Datenbank MySQL und bot mit ext/mysql eine Schnittstelle zu ihr an. Diese uralte API fehlt in PHP 7, sie war schon in Version 5.5 als überholt (deprecated) markiert. Vor dem Umstieg auf das neue PHP müssen Entwickler also gegebenenfalls ihre Software auf mysqli oder das datenbankunabhängige PDO umstellen. Entscheidungshilfe dabei gibt ein Wiki-Beitrag.
PHP-Nutzer müssen aber nicht nur auf Altes verzichten, sie bekommen mit Version 7 auch zahlreiche neue Features, die das Arbeiten mit der Skriptsprache sicherer und komfortabler machen sollen. So können Funktionsdefinitionen nun den Typ des Rückgabewerts festlegen. Versucht die Funktion, einen davon abweichenden Wert zurückzugeben, führt das zu einem Laufzeitfehler. Bislang ist an dieser Stelle nur ein einziger Datentyp zulässig, es gibt jedoch bereits Überlegungen, mehrere zu gestatten.
Auch Funktions- und Methodendefinitionen können die skalaren Datentypen int, float, string und bool für ihre Parameter festlegen. Sinnvolle Umwandlungen führt das Laufzeitsystem in der Regel durch, so interpretiert es etwa den String "1.0" als Ganzzahl, wenn die Funktion eine solche erwartet. Eine strikte Typprüfung lässt sich durch declare(strict_types=1) erzwingen, das als erstes Statement in der Datei stehen muss und für alle in ihr definierten Funktionen gilt. Dann hat das Übergeben eines Parameters vom falschen Typ einen Laufzeitfehler zur Folge.
PHP 7 führt einen "Null Coalesce"- und einen "Combined Comparison"-Operator, die es auch in anderen Sprachen gibt. Den ersten schreibt man ?? und benutzt ihn zum Abkürzen von if-then-else-Zweigen, etwa so: $a = $b ?? 1. Das setzt die Variable $a auf den Wert von $b, wenn $b existiert und nicht null ist. Sonst erhält $a den Wert 1. Diese Verkürzung dürfte unter anderem das Auswerten von GET- und POST-Parametern vereinfachen. So übernimmt $username = $_GET['user'] ?? 'nobody'; den Wert der GET-Variablen "user", wenn sie vorhanden ist. Andernfalls weist sie $username den Wert "nobody" zu.
Der auch als "Spaceship" bekannte "Combined Comparison"-Operator "<=>" liefert den Wert 0, wenn seine beiden Argumente gleich sind. Ist das erste kleiner als das zweite, liefert er -1; im umgekehrten Fall 1. Das erlaubt kompaktere Vergleiche, etwa in Sortierfunktionen. Als Spaceship-Parameter sind alle Typen zulässig, die auch die bisherigen Vergleichsoperatoren wie "<=" erlauben, es finden gegebenenfalls dieselben Typwandlungen statt.
Analog zu anonymen Funktionen, die PHP durch Closures erzeugen kann, erhält Version 7 anonyme Klassen. Die Analogie ist jedoch nicht vollständig: Während man eine anonyme Funktion in einer Variablen speichern und diese dann wie einen Funktionsaufruf verwenden kann, liefert die jetzige Implementierung anonymer Klassen ein Objekt. Einer ihrer Haupteinsatzbereiche soll denn auch das "Mocking" sein, etwa für Testzwecke.
Ein Jahr Zeit fĂĽr den Umstieg
Eine Motivation für die komplette Überarbeitung und Optimierung des PHP-Kerns war die Arbeit von Facebook an seiner HipHop Virtual Machine, die PHP-Code wesentlich schneller ausführte. Der Konkurrent setzte die PHP-Entwickler auch hinsichtlich des Funktionsumfangs der Sprache unter Druck. So führte HHVM etwa Generatoren und typisierte Rückgabewerte von Funktionen zuerst ein. Wer Wert auf viel Tempo legt, kommt nun in vielen Fällen ohne Facebooks Software aus, muss aber unter Umständen PHP selbst mit geeigneten
Optionen ĂĽbersetzen.
Der aktive Support für PHP 5 endet im August 2016, ein Jahr länger wird es noch Patches für Sicherheitslücken geben. Entwickler und Anwender können und müssen sich also darauf einstellen, ihre Software rechtzeitig auf die neue PHP-Version zu migrieren. Mit klaren Festlegungen zur Support-Dauer wollen die Entwickler einen Fehler beim Erscheinen von PHP 5 vermeiden: Damals hatten sie kein klares Ende für Version 4 vorgegeben, die deshalb noch lange zu warten war.
PHP 7 steht als Quellcode zum Download bereit. An derselben Stelle finden sich auch Binaries für Windows. Fertige Binärpakete für Debian und CentOS bietet Zend an.
Sebastian Bergmann
ist Diplom-Informatiker und Mitgründer von thePHP.cc (The PHP Consulting Company). Er hat langjährige Erfahrung in Consulting, Coaching und Training für PHP-Entwickler.
Christian Kirsch
war 16 Jahre lang iX-Redakteur und arbeitet als IT-Journalist.
(ane)