Direkt zum Inhalt
Niclas Timm
PHP 8

Mit PHP 8 wurde eine neue Hauptversion der beliebten Programmiersprache veröffentlicht. Wir zeigen Ihnen die wichtigsten Neuerungen.

PHP ist eine der weltweit am weitesten verbreiteten Programmiersprachen und kommt sowohl bei kleinen Homepages als auch bei Tech-Giganten wie Facebook zum Einsatz. Außerdem bauen die erfolgreichsten Content-Management-Systeme wie Drupal oder WordPress auf PHP auf. Die von Rasmus Lerdorf ins Leben gerufene Sprache erschien zunächst 1995 und seitdem werden Hauptversionen in einem Dreijahresrhythmus veröffentlicht. Am 26.11.2020 wurde die Version PHP 8.0 veröffentlicht, welche auf die Version 7.4 folgte. In diesem Artikel erfahren Sie alles, was Sie über die neue Version wissen müssen.

Achtung beim Wechsel

Bevor Sie Ihr Projekt auf die Version 8 updaten sollten Sie eine gründliche Prüfung Ihrer Code-Basis durchführen. Funktionen die in PHP 7 als veraltet gekennzeichnet waren, werden in PHP 8 nicht mehr unterstützt und können Fehler verursachen, wenn sie nicht entfernt werden. Eine Liste der veralteten Funktionen in PHP 7.4 finden Sie hier.

JIT (Just-In-Time) compiler

Der Just-In-Time Compiler (JIT) ist das wohl meist erwartete neue Feature in PHP. Um zu verstehen, was der JIT ist und welche Vorteile dieser bringt, muss man zunächst verstehen, wie PHP Code ausgeführt wird. Vereinfacht gesagt wird der Code an die sog. Zend Engine übergeben, welche daraus in mehreren Schritten maschinenlesbaren Code generiert. Dieser Prozess muss bei jeder Ausführung des PHP-Codes durchgeführt werden und kann dementsprechend recht zeitintensiv sein.

Mit dem JIT Compiler erfolgt nun ein weiterer Zwischenschritt, bei dem der Code nicht durch die Zend Engine in mehreren Zwischenschritten durchläuft, sondern direkt in maschinenlesbaren Code kompiliert wird. Es gäbe allerdings keine Zuwächse in der Performance, wenn der gesamte Quellcode kompiliert würde. Deswegen muss der JIT selbst entscheiden, welche Teile des Quellcodes kompiliert werden sollen und welche nicht. 

Wie bereits erwähnt ist der große Vorteil eines JIT, dass er die Performance deutlich verbessern kann. Wie groß der Einfluss ist hängt letztlich aber von der Art des Programms ab, das ausgeführt wird. Bei herkömmlichen Webanwendungen ist der Performance-Boost eher gering, da ein Großteil der Anwendungslogik mit Datenbankabfragen beschäftigt ist, auf deren Geschwindigkeit der JIT Compiler keinen Einfluss hat. Größere Verbesserungen lassen sich eher in anderen Bereichen erkennen, die normalerweise nicht sofort mit PHP in Verbindung gebracht werden, etwa im Machine Learning. Das kann also dazu beitragen PHP als eine General-Purpose-Language zu etablieren, also eine Programmiersprache, die auch außerhalb des Webs Anwendung findet.

Constructor property promotion

Wer schon einmal objektorientiertes PHP geschrieben hat kennt folgende Unannehmlichkeit:

class Person {
    public string $name;

    public string $address;

    public function __construct(
        string $name, 
        string $address,
        ) {
        $this->name = $name;
        $this->address = $address;
    }
}

Das ist eine Menge Boilerplate-Code, um die Properties der Klasse zu befüllen. Insbesondere wenn es mehrere Properties gibt kann das zum echten Zeitfresser werden und den Code unnötig lang werden lassen. In der Version 8.0 gibt es nun die Möglichkeit, die Properties direkt im Constructor zu deklarieren:

class Person {
 public function __construct(
        public string $name, 
        public string $address,
        ) {}
}

Diese Schreibweise führt zum selben Ergebnis wie die davor, nur mit viel weniger Code. Anstatt zunächst die Properties zu definieren, und diese dann innerhalb des Constructors mit den übergebenen Argumenten zu befüllen, werden die Properties inklusive des Access Modifiers direkt in den Argumenten des Constructors deklariert und befüllt. Der Funktionskörper kann dann sogar leer bleiben - PHP weiß, was zu tun ist! Falls Sie sich übrigens mehr Informationen über objektorientierte Programmierung in PHP wünschen haben wir in unserem Blog den passenden Artikel für Sie: Objektorientierte Programmierung: Erklärt am Beispiel von Drupal.

Typisierung

Types in PHP haben einen langen Weg hinter sich. PHP ist “weakly typed”, was bedeutet, dass eine Typisierung bei Variablen und Klassen nicht nötig ist. Beispielsweise ist es nicht nötig anzugeben, ob eine Variable eine Zeichenkette oder eine Nummer ist. Das vereinfacht zwar das schreiben von Code, kann aber im Laufe der Zeit zu unvorhergesehenen Bugs führen, die sich mit mehr Typsicherheit hätten vermeiden lassen. Daher wurde mit PHP 5 die (nicht verpflichtende) Möglichkeit eingeführt, Typen zu deklarieren, wobei die Liste der zur Verfügung stehenden Typen mit der Zeit weiter wuchs.

Union Types

Ein Problem mit den Typen in PHP war bisher, dass immer nur ein einziger Typ in Funktionen angegeben werde konnte. Beispielsweise so:

function myFunction (string $name): string {
	// Some logic.....
}

Dieser Code bedeutet, dass der Funktion das Argument "$name" vom Typ Zeichenkette (String) übergeben werden muss und die Funktionen eine Zeichenkette zurückgibt. Was aber, wenn eine Funktion nur einen String zurückgibt, wenn alles gut läuft und “false”, wenn etwas schiefläuft, bspw. wenn ein Sanity-Check fehlschlägt? Dieser Fall war bisher nicht abgedeckt und man musste dafür sorgen, dass immer ein string zurückgegeben wird - oder der Return type gar nicht erst angegeben wird.

Mit PHP 8 ist das nun anders. Folgender Syntax ist nun möglich:

function myFunction (string|boolean|Date $name): string|false {
	// Some logic...
}

Hier gibt es gleich mehrere Auffälligkeiten:

  1. Das Argument "$name" kann nun entweder vom Typ String, Boolean oder Date sein. Die verschiedenen Möglichkeiten werden durch eine Pipe (“|”) getrennt.
  2. Der Rückgabetyp ist nun "string|false". Das bedeutet, dass entweder eine Zeichenkette oder false zurückgeben wird. Man hätte genauso gut "string|boolean" schreiben können, aber "false" ist noch deskriptiver.

“Mixed” als Rückgabewert

In PHP 8 wird nun auch der Rückgabewert "mixed" unterstützt. Dadurch wird folgendes möglich:

function myFunc (): mixed {
	// Some logic...
}

Der "mixed" Typ sorgt programmiersprachen-übergreifend für Diskussionen. Denn was ist der Sinn von (starker) Typisierung, wenn man diese dann einfach umgeht? Dann könnte man die Angabe des Rückgabewerts auch gleich weglassen, oder? Nicht ganz. Denn eine fehlende Angabe des Rückgabewerts kann vieles bedeuten, z.B. das nichts zurückgegeben wird, das der Rückgabetyp in PHP nicht angezeigt werden kann oder dass es eins von vielen verschiedenen Rückgabewerten sein kann. Durch die Angabe von "mixed" wird eindeutig angegeben, dass es sich um den letzten der drei Fälle handelt.

“Static” als Rückgabewert

Bisher war es möglich, "self" als Rückgabewert einer Funktion anzugeben. Nun ist es auch möglich, "static" als Rückgabewert zu verwenden:

class MyClass {
	public function myFunc(): static {
		return new static();
    }
}

Benannte Argumente

Benannte Argumente geben dem Programmierer die Möglichkeit, Argumente an eine Funktion anhand ihres Namens anstatt der Position zu übergeben. Das sieht dann so aus:

function myFunc ($name, $address) {
	// Some logic...
}

myFunc(address: 'Wayne Manor', name:'Bruce Wayne')

Obwohl in der Definition der Funktion "$address" an zweiter Stelle in den Argumenten steht, kann beim Aufruf der Funktion die Adresse als erstes übergeben werden, indem das Argument mit “address:” gekennzeichnet wird. Dadurch muss sich der Programmierer einerseits nicht merken, in welcher Reihenfolge die Argumente anzugeben sind und andererseits ist diese Schreibweise deskriptiver.

“Throw” als Ausdruck, nicht als Aussage

Bisher konnte "throw" nur als Aussage (Statement) verwendet werden. Ab PHP 8 wird dies geändert, sodass "throw" nun ein Ausdruck (Expression) ist. Das ermöglicht eine Vielzahl von neuen Stellen, an denen nun Ausnahmen (Exceptions) geworfen werden können. Beispielsweise:

$my_var = $variables['some_index'] ?? throw new Error();

Neue Funktionen

Natürlich kommt PHP 8 auch mit einigen neuen Funktionen, die dem Programmierer das Leben erleichtert. Die wichtigsten Neuerungen beziehen sich dabei auf die Arbeit mit Zeichenketten.

str_contains()

Bisher musste man über die Funktion "strpos" einen kleinen Umweg gehen um herauszufinden, ob eine Zeichenkette (String) eine andere Zeichenkette enthält. Dafür gibt es jetzt eine eigene Funktion:

str_contains('This is my string and it is very cool.', 'cool') // TRUE

str_starts_with() und str_ends_with()

Zwei weitere Funktionen, in denen es um Zeichenketten geht, sind str_starts_with() und str_ends_with(). Wie die Namen vermuten lassen lässt sich damit überprüfen, ob eine Zeichenkette mit einem anderen Zeichenkette beginnt oder endet:

str_starts_with('haystack', 'hay'); // TRUE
str_ends_with('haystack', 'stack'); // TRUE

get_debug_type()

Mit dieser Funktion lässt sich der Typ einer Variable zurückgeben. Das konnte auch bisher durch die Funktion "gettype()" erreicht werden. Allerdings gibt "get_debug_type()" detailliertere Informationen zurück. Beispielsweise würde "gettype()" auf die Klasse MyClass “object” zurückgeben während "get_debug_type()" den Namen der Klasse ausgibt.

Drupal Support

Momentan wird PHP 8 von Drupal 7 (ab 7.79) und 9.1 unterstützt. Drupal 8 sowie 9.0 hingegen funktionieren nicht mit der neuen PHP Hauptversion.  Aber Achtung: Ende 2021 endet der Community-Support für PHP 7.4, also der bisher aktuellsten PHP Version. Es wird dann keine Updates mehr geben und keine Sicherheitslücken mehr geschlossen. Dann sollten Sie nicht nur ein PHP Update, sondern auch ein Drupal 9 Upgrade in Betracht ziehen. Als auf Drupal spezialisierte Agentur unterstützen wir Sie dabei sehr gerne! Sie können uns jederzeit hier gerne schreiben oder uns direkt anrufen. 

Zusammenfassung

Mit PHP 8 ist eine neue Hauptversion  veröffentlicht worden, die viele Neuerungen mit sich bringt. Insbesondere der heiß erwartete Just-In-Time Compiler soll die Programmiersprache auf das nächste Level bringen. Aber auch andere neue Features wie benannte Argumente oder neue Typen verbessern die Erfahrung für den Programmierer.