PHPs krasse Dekade: Vom Witz zum Kraftpaket (2014-2024)
Kein Witz: Wie eine Sprache vom Running Gag zum Motor für einen riesigen Teil
des modernen Webs wurde.
Einleitung: Jenseits der alten Witze
Mal ehrlich. Wenn du vor zehn Jahren schon im Development unterwegs warst, hast
du safe ein paar Lacher auf Kosten von PHP mitgenommen. Es war die Sprache der
inkonsistenten Funktionsnamen, des wilden Type-Jugglings und der absoluten
Spaghetti-Code-Albträume. Der Spruch vom “Fraktal schlechten Designs” ging durch
alle Foren und war, seien wir ehrlich, lange Zeit schmerzhaft treffend.
Spul vor bis heute. PHP ist schneller, stärker und robuster als je zuvor. Die
Witze sind lahm geworden und selbst die größten Hater zollen Respekt. Das war
kein Zufall. Das war ein Jahrzehnt knallharter Arbeit, genialem Engineering und
einer Community, die einfach Bock hatte, ihre Sprache nicht sterben zu lassen.
Lass uns mal tief eintauchen in die Schlüsselmomente von PHPs unglaublicher
Comeback-Story.
Teil 1: Das Fundament aus dem Chaos (Die Zeit vor PHP 7)
Bevor die Sprache selbst gefixt werden konnte, musste erstmal das Ökosystem
aufgeräumt werden. Die frühen 2010er waren der Wilde Westen.
Das Leben vor Composer: Willkommen in der Dependency-Hölle
Stell dir 'ne Welt ohne npm install
oder pip install
vor. Genau das war PHP.
Um 'ne Library wie Twig oder Monolog zu nutzen, musstest du:
- Das Tarball manuell runterladen.
- Es in ein
vendor/
-Verzeichnis entpacken. - Einen Haufen
require_once
-Statements in der richtigen Reihenfolge
reinhacken, um die Files zu laden. - Dich selbst um Versionskonflikte kümmern. Wenn Library A Library C v1.0
brauchte und Library B v1.1, hattest du richtig Spaß.
Das Ergebnis? Jedes Framework hat sein eigenes Süppchen gekocht, mit eigenem
Ökosystem und Autoloader. Isolierte Code-Inseln, die nicht miteinander reden
konnten. Total ätzend.
Akt I: Composer und Packagist
Composer, 2012 released, war der wichtigste Katalysator, um PHP professionell zu
machen. Das Ding hat zwei Probleme genial gelöst:
- Dependency Management: In die
composer.json
schreibst du rein, was du
brauchst. Composer checkt dann den ganzen Abhängigkeits-Graphen, löst alles
auf und lädt die richtigen Versionen. Diecomposer.lock
-Datei sorgt dafür,
dass jeder im Team exakt die gleichen Versionen hat. Ende der “Bei mir
geht’s aber”-Diskussionen. - Autoloading: Composer generiert eine einzige
vendor/autoload.php
.
Einbinden, fertig. Alle Dependencies sind bei Bedarf da. Mega praktisch.
Akt II: Die PHP-FIG und der PSR-Waffenstillstand
Nachdem Composer das Teilen von Code ermöglichte, mussten wir den Code noch
kompatibel machen. Die PHP Framework Interoperability Group (PHP-FIG) hat die
verfeindeten Framework-Lager an einen Tisch geholt, um gemeinsame Standards
(PSRs) zu schaffen.
- PSR-4 (Autoloader): Der Geniestreich. Ein Standard, der einen Namespace
auf einen Pfad mappt (z.B.My\App\Foo
->src/Foo.php
). Composer hat das
implementiert und plötzlich haben alle beim Laden von Files dieselbe Sprache
gesprochen. - PSR-1 & PSR-12 (Coding Style): Eine Basis für die Code-Formatierung. Tools
wiePHP-CS-Fixer
konnten jetzt automatisch für einen einheitlichen Style
sorgen. Code von anderen lesen war plötzlich kein Krampf mehr. - PSR-3 (Logger), PSR-7 (HTTP Messages), etc.: Gemeinsame Interfaces. Eine
Library konnte jetzt gegenPsr\Log\LoggerInterface
typen, egal ob der User
Monolog oder was anderes reingab. Das hat Libraries erst wirklich
Framework-unabhängig gemacht.
Mit diesem Fundament war die Bühne für das Hauptereignis bereitet.
Teil 2: Die PHP 7 Performance-Revolution
PHP 7.0, im Dezember 2015 released, war der Quantensprung. Geboren aus dem
PHP-NG (Next Generation)-Projekt, einem Branch, der die Zend Engine von
Grund auf neu geschrieben hat.
Unter der Haube: Die Magie der Zend Engine 3
Die “2x schneller”-Ansage war kein Marketing-Gerede. Das war das Ergebnis von
tiefgreifenden, fundamentalen Änderungen.
Das Zval-Makeover
In PHP 5 war jede Variable ein zval
-Struct, das einzeln auf dem Heap lag.
Unglaublich ineffizient.
- PHP 5
zval
: 24 Bytes schwer, plus ein Ref-Counter. Variablen kopieren
hieß, diesen Zähler hochzusetzen. - PHP 7
zval
: Nur noch 16 Bytes. Aber viel wichtiger: Bei einfachen Typen
wie Integers, Booleans und null wird der Wert direkt im zval gespeichert.
Keine Allokation auf dem Heap mehr. Das machte sie zu echten Werten, nicht zu
referenzgezählten Objekten, was den Overhead massiv reduzierte und die
Cache-Lokalität verbesserte. Ein riesen Ding!
Optimierte Datenstrukturen
Hashtables (das Ding hinter PHP-Arrays) wurden neu designt, um kleiner und
schneller zu sein. Die internen Pointer wurden neu angeordnet, was sie für
moderne CPUs viel Cache-freundlicher machte. Das ist ein Hauptgrund, warum
Array-lastige Apps so einen krassen Speed-Boost bekommen haben.
Der Beginn einer strengeren Sprache
Performance war die Schlagzeile, aber die Einführung eines stärkeren
Type-Systems war für die Zukunft der Sprache wohl noch wichtiger.
- Scalar Type Declarations (PHP 7.0): Zum ersten Mal konnten wir Typen wie
int
,float
,string
undbool
für Funktionsparameter erzwingen.
Standardmäßig im “koerziven” Modus (ein String"1"
wurde für einen
int
-Parameter akzeptiert), aber mitdeclare(strict_types=1);
am Anfang der
Datei kriegst du den strikten Modus, der dann einenTypeError
wirft. - Return Type Declarations (PHP 7.0): Funktionen konnten endlich
deklarieren, was sie zurückgeben. APIs wurden so selbstdokumentierend. - Nullable Types (PHP 7.1): Das
?
-Präfix (z.B.?string
) machte den
Umgang mitnull
explizit und sicher. - Typed Properties (PHP 7.4): Das war das letzte Puzzleteil für die
grundlegende Typsicherheit. Wir konnten Typen direkt an Klassen-Properties
schreiben, was eine riesige Fehlerquelle eliminierte.
// PHP 7.4: Eine Klasse mit voller Basis-Typsicherheit
declare(strict_types=1);
class User
{
public int $id;
public string $name;
public ?string $email;
}
Teil 3: Die PHP 8-Ära: Ausdrucksstark und erwachsen
Wenn PHP 7 das Aufräumen der Vergangenheit war, dann ist PHP 8 das Gestalten der
Zukunft.
Der JIT (Just-In-Time) Compiler
PHP 8.0 brachte den JIT-Compiler, der auf OPcache (dem Bytecode-Cache) aufsetzt.
- Wie’s funktioniert: OPcache kompiliert deine
.php
-Files in Opcodes. Der
JIT kann dann “heiße” Sequenzen dieser Opcodes schnappen und sie zu echtem
Maschinencode kompilieren, der direkt auf der CPU läuft. Für diesen Code-Pfad
wird die Zend VM dann umgangen. - Die Realität: Für die meisten Web-Apps, die eh nur auf die Datenbank oder
APIs warten (I/O bound), bringt der JIT kaum was. Der Flaschenhals ist nicht
die CPU. Aber für langlebige CLI-Skripte oder rechenintensive Sachen
(Bildverarbeitung, Datenanalyse) kann der JIT die Performance um den Faktor
2-10 steigern und macht PHP für neue Anwendungsfälle interessant.
Eine Flut an geilen Features für Entwickler
PHP 8.x hat uns mit Features überschüttet, die die Code-Qualität und unsere
Laune drastisch verbessert haben.
Attribute: Das Ende der Annotations-Hölle
Früher haben Frameworks Kommentare geparst (/** @Route("/foo") */
), um an
Metadaten zu kommen. Das war langsam, fehleranfällig und nicht Teil der Sprache.
PHP 8 hat native Attribute eingeführt.
Vorher (Annotations in Docblocks):
/**
* @Route("/api/posts/{id}", methods={"GET"})
*/
public function getPost(int $id): Response
{
// ...
}
Nachher (Native Attribute):
#[Route('/api/posts/{id}', methods: ['GET'])]
public function getPost(int $id): Response
{
// ...
}
Das ist jetzt echter Code, den die Engine versteht und den man per
Reflection-API auslesen kann. Funktioniert geil.
Constructor Property Promotion
Dieses Feature hat den Boilerplate-Code in Value Objects und DTOs extrem
reduziert.
Vorher:
class Money
{
public int $amount;
public Currency $currency;
public function __construct(int $amount, Currency $currency)
{
$this->amount = $amount;
$this->currency = $currency;
}
}
Nachher:
class Money
{
public function __construct(
public int $amount,
public Currency $currency,
) {}
}
Das Ergebnis ist dasselbe, aber viel sauberer und kürzer.
Mächtigere Typen: Union, Intersection und Enums
- Union Types (8.0):
int|string
- Die Variable kann einer dieser Typen
sein. - Enums (8.1): Eine native, typsichere Art, um erlaubte Werte zu definieren.
Das alte Muster mit Klassenkonstanten war damit endlich broken. - Readonly Properties (8.1): Unveränderlichkeit auf Sprachebene.
- Intersection Types (8.1):
Iterator&Countable
- Das Objekt muss alle
Typen implementieren. - DNF Types (8.2): Erlaubt die Kombination von Union- und Intersection-Typen
für komplexe Regeln.
Teil 4: Der Faktor Mensch: Eine Community wird erwachsen
Das letzte Puzzleteil war nicht technisch, sondern sozial und organisatorisch.
Der “Bus-Faktor” und die PHP Foundation
Jahrelang wurde die PHP-Entwicklung von einer kleinen Gruppe von
Core-Entwicklern getragen, allen voran Nikita Popov. Als er 2021 ankündigte,
kürzerzutreten, um sich auf LLVM zu konzentrieren, hätte das eine Krise auslösen
können. Was passiert, wenn dein wichtigster Entwickler geht?
Die Reaktion war ein Zeichen der Reife des Ökosystems. Statt Panik zu schieben,
haben sich die großen Player im PHP-Space (JetBrains, Automattic, Laravel,
Symfony und viele mehr) zusammengetan und The PHP Foundation gegründet. Das
ist ein Open Collective, das Geld sammelt, um Core-Entwicklern marktübliche
Gehälter zu zahlen. Das sichert die Wartung und Entwicklung der Sprache
nachhaltig und macht sie unabhängig von der Freizeit von Freiwilligen oder einem
einzelnen Sponsor.
Fazit: Ein neuer Ruf, in Code geschmiedet
Das PHP von 2024 ist ein anderes Kaliber. Es ist eine Sprache, die systematisch
und durchdacht von der Engine bis zu den Ökosystem-Standards neu entwickelt
wurde. Die Reise von einem “Fraktal schlechten Designs” zu einer modernen,
performanten und beliebten Sprache ist eine der großen Erfolgsgeschichten der
Softwareentwicklung.
Wenn du PHP vor Jahren abgeschrieben hast, ist es an der Zeit, wieder
reinzuschauen. Du wirst die Sprache, an die du dich erinnerst, nicht
wiedererkennen. Du findest ein modernes, mächtiges und kampferprobtes Werkzeug,
das für das nächste Jahrzehnt bereit ist.
Welches Feature der letzten Dekade hat deinen Arbeitsalltag am meisten
verändert? Schreib’s mir auf Twitter oder LinkedIn.
Weiterführende Literatur: