Neue Features, bessere Performance: Das kann der PHP-5-Nachfolger: PHP 7 ist da!
Der PHP-Versionssprung von 5 auf 7 mag zunächst verwirrend erscheinen. Tatsächlich gab es bereits 2005 den Versuch, ein neues Major Release von PHP zu veröffentlichen, das vollständige Unicode-Unterstützung bieten sollte. Aufgrund von Schwierigkeiten bei der Implementierung dieser Unicode-Unterstützung wurde die Weiterentwicklung von PHP 6 jedoch im Jahr 2010 aufgegeben. Zahlreiche andere für PHP 6 vorgesehene Features flossen daraufhin in die PHP-Versionen 5.3 und 5.4 ein.
Zudem erschienen damals zahlreiche Bücher und Tutorials zu PHP 6, die heute völlig veraltet sind und mit denen Anwender eines „neuen PHP 6“ nichts mehr anfangen könnten. Aus diesen Gründen wurde beschlossen, für das jetzige Major Release die Versionsnummer 6 zu überspringen, damit keine Verwechslungsgefahr mit dem „alten PHP 6“ aus dem Jahr 2005 besteht. Die vollständige Argumentation für die Namenswahl lässt sich unter [1] nachvollziehen.
Neue Sprachfeatures
PHP 7 implementiert einige neue Sprachfeatures, die die Arbeit mit PHP vereinfachen, häufige Fehler vermeidbarer machen oder einfach Unschönheiten der Vergangenheit ausbügeln. Die interessantesten neuen Funktionen stellen wir im Folgenden vor.
Skalare Typhinweise
Für Methodenparameter und Rückgabewerte lassen sich nun Datentypen angeben. Das stellt sicher, dass in eine Funktion nur Werte eines bestimmten Datentyps übergeben werden können, und eine Methode immer einen festgelegten Typ zurückliefert:
function add(int $a, int $b): int { return $a + $b; }
Listing 1
Standardmäßig konvertiert PHP Parameter des falschen Typs automatisch. Die Funktion aus dem obigen Beispiel lässt sich also trotz der Typhinweise wie folgt mit String-Parametern aufrufen:
add("2", "3"); // Rückgabe: int(5)
Listing 2
Die Typhinweise sorgen in diesem Beispiel dafür, die Eingabewerte der Methode beim Aufruf in integer-Werte zu konvertieren. Innerhalb der Funktion ständen $a und $b somit wieder als integer-Variablen zur Verfügung. Die Typhinweise auf diese Weise zu verletzten, verursacht jedoch eine E_NOTICE-Fehlermeldung.
Um eine noch strengere Typsicherheit zu erzwingen, kann in einer Quelltextdatei das Statement „declare(strict_types=1);“ zum Einsatz kommen. Läuft ein PHP-Programm mit strikter Typisierung, wirft es bei Verletzung eines Typ-Hinweises einen TypeError aus, der – sofern er nicht gefangen wird – das Programm terminiert.
Neue Operatoren
Außerdem führt PHP 7 zwei neue Operatoren ein: den spaceship-Operator (<=>) und den null coalesce-Operator (??). Ersterer kombiniert die „größer als“- und „kleiner als“-Operatoren:
$c = $a <=> $b; // -1, wenn $a < $b // 1, wenn $a > $b // 0, wenn $a == $b // Kurzform für: $c = ($a > $b) ? 1 : (($a < $b) ? -1 : 0);
Listing 3
Der null coalesce-Operator kann dazu dienen, vor der Nutzung einer Variablen zu überprüfen, ob diese überhaupt gesetzt ist:
$a = $b ?? "default"; // Kurzform für: $a = isset($b) ? $b : "default";
Listing 4
Anonyme Klassen
Ähnlich wie in Java oder C# lassen sich nun so genannte Anonyme Klassen definieren [2], die nicht über einen Namen identifiziert werden. Dies ist für Klassen sinnvoll, die nur einmal benötigt werden oder deren Implementierung zu trivial für das Laden per Autoloader ist.
$a = new class { public function sayHello($who) { echo "Hello $who!\n"; } }; $a->sayHello("World");
Listing 5
Fehlerbehandlung
Ebenfalls verändert hat sich die Handhabung von Fehlern. In zahlreichen Fällen, die zuvor zur Ausgabe oder Protokollierung eines PHP-Fehlers führten, wird nun eine Instanz der Error-Klasse geworfen, die über ein catch-Statement gefangen und geordnet behandelt werden kann. Zu beachten ist, dass die neue Error-Klasse nicht von der bekannten Exception-Klasse erbt und somit nicht von catch(Exception $e)-Statements abgefangen wird. Sowohl die Error- als auch die Exception-Klasse implementieren jedoch das ebenfalls neu hinzugekommene Throwable-Interface, welches sich ebenfalls in einem catch-Block nutzen lässt:
try { // Verursacht in PHP 5 eine E_WARNING-Meldung, wenn $b == 0 // Wirft in PHP 7 nun einen DivisionByZeroError $a = 5 / $b; } catch (DivisionByZeroError $e) { // Fehlerbehandlung }
Listing 6
Was ist nicht mehr kompatibel?
PHP 7 räumt mit einigen Sprach-Features auf, die sich aus PHP-4-Zeiten gehalten haben. Diese verursachen nun eine E_DEPRECATED-Fehlermeldung oder im Extremfall gleich einen Parser-Fehler.
Grundsätzlich sind alle Funktionen und Sprach-Funktionen, die bereits in PHP 5 einen E_DEPRECATED-Fehler verursachten, nun komplett verschwunden. Die wichtigste Änderung ist hierbei die Entfernung der mysql-Extension, von welcher die mysql_*-Funktionsfamilie angeboten wird. Stattdessen fungiert nun die mysqli- oder PDO-Extension für den Zugriff auf MySQL- und MariaDB-Datenbanken. Ebenso entfernt wurde die ereg_*-Funktionsfamilie, welche bereits in PHP 5.3 zugunsten der preg_*-Funktionen wegfiel. Außerdem werden die (bisher ohnehin eher unbekannten) alternativen Open-Tags <%, <%= und <script language="php"> nicht mehr unterstützt.
Weiterhin unterstützt (jedoch nur unter Protest des Interpreters) werden beispielsweise PHP 4-Konstruktoren, die denselben Namen tragen wie die definierende Klasse:
class MyClass { public function MyClass() { // E_DEPRECATED: Methods with the same name as their class will not // be constructors in a future version of PHP; MyClass has a // deprecated constructor in example.php on line 3 } }
Listing 7
Eine Zusammenfassung aller nun veralteten Sprachfunktionen findet sich unter [3].
Performanceverbesserungen
Bereits die letzten PHP-Versionen konnten jeweils deutliche Performanceverbesserungen erreichen. PHP 7 steigert dies noch einmal. Die Abbildungen unten zeigen, dass PHP 7 bei vielen Anwendungssystemen die durchschnittliche Seitengenerierungszeit um circa 40 Prozent verringern und deutlich mehr Anfragen pro Sekunde verarbeiten kann. Allerdings erreicht PHP 7 damit noch nicht ganz die Leistungsfähigkeit der alternativen PHP-Laufzeitumgebung HHVM, die Anfang letzten Jahres von Facebook vorgestellt wurde [4].
Alle Benchmarks wurden mit Siege [5] erstellt (c=100). Die zur Erstellung der Benchmarks genutzten Skripte stehen ebenfalls unter dem obigem Link auf Github zur Verfügung.
Werkzeuge für die Migration
Um den Wechsel von PHP 5 auf PHP 7
zu erleichtern, stehen verschiedene Werkzeuge zur Verfügung. Das
Composer-Paket sstalle/php7cc [6] beispielsweise enthält ein Kommandozeilen-Werkzeug, welches durch
statische Code-Analyse ein existierendes Projekt nach nicht mehr
unterstützten Sprach-Konstrukten durchsucht.
Das Paket kann per Composer installiert werden:
composer require --dev sstalle/php7cc
Listing 8
Anschließend erstellt folgender Befehl einen Bericht über die Kompatibilität des Projekts:
./vendor/bin/php7cc
Listing 9
Untenstehender Screenshot zeigt eine Beispielausgabe von php7cc.
Eine der größten Umstellungen bei der Migration einer PHP-Applikation von PHP 5 auf PHP 7 dürfte der Wegfall der mysql-Extension sein. Glücklicherweise gibt es Werkzeuge, die die Migration auf eine der Nachfolger-Bibliotheken (wie beispielsweise mysqli) automatisieren können. Das MySQL-Converter-Tool lässt sich per Git von GitHub beziehen und dann über die Kommandozeile ausführen:
git clone git://github.com/philip/MySQLConverterTool.git php MySQLConverterTool/cli.php –d path/to/application –p '*.php' –u
Listing 10
Das MySQL-Converter-Tool sucht nach allen genutzten mysql_*-Funktionen in einem Programm und ersetzt sie soweit möglich mit ihren entsprechenden mysqli_*-Äquivalenten. Diese automatisierte Quelltexttransformation kann in einem Migrationsprojekt sehr viel manuelle (und somit aufwändige und fehleranfällige) Arbeit einsparen.
Fazit
Mit Version 7 hat PHP einen großen Schritt nach vorne gemacht und konnte insbesondere aus Performance-Sicht einen guten Teil des an die HHVM verlorenen Bodens wieder gut machen. Die Möglichkeit, mit typisierten Variablen zu arbeiten, tut der Sprache ebenfalls gut und lässt sich dazu nutzen, die Codequalität in Projekten deutlich zu erhöhen und häufige, sich aus der vollständig dynamischen Typisierung ergebende Programmierfehler zu vermeiden. Darüber hinaus räumt PHP 7 mit längst überflüssigen Altlasten aus der PHP-4-Ära auf.
Für ältere Projekte gilt grundsätzlich: Läuft das Programm unter PHP 5.6, ohne E_DEPRECATED-Fehlermeldungen zu generieren, ist es mit hoher Wahrscheinlichkeit auch unter PHP 7 lauffähig. Andernfalls ist mit einem höherer Migrationsaufwand zu rechnen. Speziell die Entfernung der früher sehr beliebten mysql-Extension kann vielen älteren Projekten zu schaffen machen. Aufgrund der deutlichen Performancevorteile und neuen Sprachfeatures, die eine hochqualitativere Softwareentwicklung ermöglichen, kann jedoch auch für Altprojekte eine Migration auf PHP 7 sinnvoll sein.