PHP 8.1: Die wichtigsten Neuerungen

Bereits seit 27 Jahren existiert die Skriptsprache PHP und ist einfach allgegenwärtig im Web. Nachdem im November 2020 die neue Major-Version PHP 8.0 erschien, ist nun die Version 8.1 verfügbar. Wir haben dir alle wichtigen Features zusammengetragen, die PHP 8.1 mit sich bringt. Du kannst dich auf wirklich eine Menge neuer Features und auch auf eine weitere Performance-Verbesserung freuen.

Wichtig: Aufgrund der Änderungen in PHP 8.1 musst du gegebenenfalls Anpassungen im Code machen. Zwar ist die Version 8.1 kein Major-Update, dennoch sind einige Änderungen möglicherweise nicht abwärtskompatibel. Nötige Anpassungen findest du beispielsweise hier bei php.net.

WordPress-User aufgepasst: PHP 8.1 ist noch nicht mit der aktuellen WordPress-Version (5.8) kompatibel. Das wird erst ab der WordPress-Version 5.9 funktionieren.

Als checkdomain-Kundin oder -Kunde kannst du PHP 8.1 ganz einfach im Kundenportal unter „Domains“ und dann weiter unter dem Punkt „PHP-Einstellungen“ auswählen.

PHP 8.1 – das ist neu:

Performance

PHP 8.1 bringt wieder einige Performance-Verbesserungen mit. So wurden bei der Version 8.1 auch Performance-Verbesserungen am Opcache vorgenommen. „Inheritance Cache“ verknüpft beispielsweise alle eindeutig abhängigen Klassen (z.B.: Methoden, Traits, Schnittstellen) miteinander, die zuvor separat kompiliert werden mussten. Im Opcache shared memory können diese nun zwischengespeichert werden, was die Perfomance optimiert. Dieses Feature kannst du ohne Änderung am Programmcode verwenden.

Experten haben beispielsweise bei PHP 8.1 im Vergleich zur Version 8.0 eine Geschwindigkeitssteigerung von 3,5 Prozent bei WordPress festgestellt.

Deprecated: Warnungen bei null-Werten

Interne PHP-Funktionen erlauben „null“ als Argument, obwohl der Typ des Arguments nicht „nullable“ ist. Einige Funktionen (Polyfills) bilden die internen Funktionen in PHP nach, um den Umstieg auf neue Versionen zu erleichtern. Diese können allerdings aktuell einige interne Funktionen nicht korrekt abbilden, da selbst geschriebene Funktionen nur dann bei skalaren Typen ein „null“ als Parameter erhalten dürfen, wenn der Parameter auch als „nullable“ angegeben wurde.

Das wird nun in PHP 8.1 auf interne Funktionen übertragen – allerdings zunächst mit einer Deprecate-Warnung. Für PHP-Versionen ab 9.0 ist geplant, dass bei diesen Funktionen ein „TypeError“ erzeugt wird. Wenn du also jetzt noch „null“ als Parameter an die internen Funktionen übergibst, könntest du später Schwierigkeiten im Code haben.

Neue Funktion array_is_list()

In PHP kannst du einfach mit einem Array komplexe Strukturen abbilden. So kannst du während der Laufzeit neue Array-Keys hinzufügen und vorhandene verändern. Doch Achtung: diese Flexibilität bringt Performanceprobleme mit sich.

Ein PHP-Array kannst du optimieren, wenn du die Array-Keys durchnummerieren lässt: von 0 bis zur Anzahl der Elemente. Diese Optimierung lässt sich allerdings derzeit schwer umsetzen, da allein die Überprüfung der Keys schon sehr aufwendig ist. Der aktuelle Polyfill für die Funktion ist hier abgebildet:

function array_is_list(array $array): bool {

  $expectedKey = 0;

  foreach ($array as $i => $_) {

    if ($i !== $expectedKey) { return false; }

    $expectedKey++;

  }

  return true;

}

(Quelle wiki.php.net)

Mit der Funktion „array_is_list“ kannst du die enthaltenen Array-Keys beginnend beim Wert 0 prüfen, ob eine nummerische Reihenfolge erkennbar ist.

array_is_list([]); // true

array_is_list([‚apple‘, 2, 3]); // true

array_is_list([0 => ‚apple‘, ‚orange‘]); // true

// The array does not start at 0

array_is_list([1 => ‚apple‘, ‚orange‘]); // false

// The keys are not in the correct order

array_is_list([1 => ‚apple‘, 0 => ‚orange‘]); // false

// Non-integer keys

array_is_list([0 => ‚apple‘, ‚foo‘ => ‚bar‘]); // false

// Non-consecutive keys

array_is_list([0 => ‚apple‘, 2 => ‚bar‘]); // false

(Quelle PHP Wiki)

Mit der nativen Implementierung der Funktion könntest du den Code noch performanter umsetzen, da auf diese Weise nicht mehr davon ausgegangen werden muss, dass die Array-Keys einen nichtnumerischen Wert besitzen werden. Damit wird PHP in der Zukunft noch performanter werden.

Auch wichtig: Eine PHP-Array-Liste samt ungeordneten Schlüsseln ist eine potenzielle Fehlerquelle, da eine strikte Einhaltung der Listenanforderung das A und O ist. Die Funktion array_is_list trägt daher wunderbar dazu bei, dass du den Code bezüglich Arrays fehlerfrei hältst.

$GLOBALS als Referenz verbieten

Seit Anfang an existieren in PHP globale Variablen, die dir viel Flexibilität bieten. Oft entstehen mit dieser Flexibilität aber auch Seiteneffekte. Mit dem RFC ist es verboten $GLOBALS-Variablen als Referenz einer anderen Variablen zuzuweisen. Wir schauen uns das hier einmal genauer an:

$a = 1;

$GLOBALS[‚a‘] = 2;

var_dump($a); // int(2)

Die Variable „$a“ wird als Compiled-Variable intern abgespeichert, damit schneller auf Variablen zugegriffen werden kann. Damit „$a“ über „Globals“ modifiziert werden kann, werden die Array-Keys von „Globals“ so abgespeichert, dass die Keys einen Zeiger auf die Variablen haben.

Allerdings: Das „$GLOBALS-Array“ ist aus den normalen Arrayfunktionalitäten ausgenommen. Beispielsweise ist es möglich, „$GLOBALS“ einem Array zuzuweisen, damit dieses Array einen Zeiger auf „$GLOBALS“ hat. Damit kann das neue Array vorhandene Variablen verändern, wie du im folgenden Code-Beispiel sehen kannst:

$a = 1;

$globals = $GLOBALS; // Ostensibly by-value copy

$globals[‚a‘] = 2;

var_dump($a);

Explizite Octal Integer Notation

In den vergangenen Jahren hat sich sehr viel bei PHP getan, vor allem in Bezug auf Vergleichen von Strings und Integers. Seit PHP 8 sind die Vergleiche expliziter, allerdings führt das zu neuen Problemen:

Es gibt Zahlen, die Buchstaben enthalten – beispielsweise eine Hexadezimal- oder Binärzahl.

Mit „$x = 0b1101;“ kann einer Variablen der binäre Wert zugeordnet werden. Mit „$y = 0xBF12;“ hast du die Möglichkeit, einfach mit einer „0“ am Anfang zu arbeiten: „$z = 016;“. Allerdings gibt es Fälle, bei denen du einen octalen Wert erhalten kannst. Daher gibt es in PHP 8 ein 0o- oder 0O-Präfix, so dass du explizit einen Wert als Octal definieren kannst:

$octal = 0o16 == 14; // hier kommt ein „true“

MySQLi default error mode

Achtung: dieses neue Feature könnte zu Problemen in deinem vorhandenen Code führen, denn seit PHP 8 wurde der PDO Error Mode auf Exception umgestellt und alle Fehlermeldungen, die von einer Datenbank kommen, werden direkt ausgegeben – außer, sie werden vorher abgefangen.

Das gleiche Verhalten soll nun auf MySQLi übertragen werden. Dort ist es aktuell genau wie beim alten PDO: Die Fehler werden nicht abgefangen und der Code wird weiter ausführt. Ab PHP 8 soll der „mysqli_report“ auf“ MYSQLI_REPORT_ERROR“ und „MYSQLI_REPORT_STRICT“ gestellt werden.

Ab PHP 8 wird hier eine Exception geworfen, doch dadurch könnten nun vorhandene Codeabschnitte, die sich auf den Silent Mode verlassen haben, Fehler ausgeben.

Wenn du dennoch die Fehler auf deinem System unterdrücken möchtest, musst du die Funktion „mysqli_report“ mit dem Parameter MYSQLI_REPORT_OFF nutzen.

Neue Funktion fsync()

Ja, die Funktion „fflush()“ gibt es in PHP schon länger. Sie erzwingt das Schreiben des gesamten Ausgabepuffers in den Dateizeiger, der als Parameter übergeben wurde.

Diese Funktion erhält aber lediglich ein „true“ oder ein „false“ vom Betriebssystem, auf dem PHP läuft. Den Inhalt muss das Betriebssystem selbst in das Dateisystem übertragen – und genau hier könnte es zu Problemen kommen, von denen PHP aber selbst nichts mitbekommt.

Mit der Funktion „fsync()“ kannst du nun aus dem Skript heraus erfahren, ob der Ausgabepuffer auch kontinuierlich geschrieben wurde, erst dann erhältst du ein „true“ bei Success.

Außerdem wurde die Funktion „fdatasync()“ eingeführt. Diese sorgt dafür, dass deine Daten wie in „fsync“ gespeichert werden, aber eben nicht die Metadaten.

Unter Windows ist die Funktion „fdatasync“ ein Alias für “fsync“, weil das Schreiben des Buffers ohne die Metadaten unter Windows nicht unterstützt wird.

Enumerations

Mit PHP 8.1 wird mit Enums (Enumerated Types) ein neues Sprachkonstrukt eingeführt, mit dem Datentypen unterstützt werden, die einen von mehreren fest definierten Werten annehmen können. Da Enums in PHP-Klassen implementiert ist, erben sie auch viele Klassen-Semantiken.

Die Syntax von Enums ähnelt denen von Traits, Klassen oder Interfaces. Zunächst werden Enums mit „enum“ gekennzeichnet und der jeweilige Name folgt, genauso wie die möglichen Werte, die mit dem Keyword „case“ eingeleitet werden. So sieht das beispielsweise aus:

enum Suit {

  case Hearts;

  case Diamonds;

  case Clubs;

  case Spades;

}

(Quelle PHP Wiki)

Außerdem sind auch Backed Enums möglich, bei denen jedem möglichen Wert, den der jeweilige Enum annehmen kann, ein interner String- oder Integer-Wert zugeordnet werden kann.

enum Suit: string {

  case Hearts = ‚H‘;

  case Diamonds = ‚D‘;

  case Clubs = ‚C‘;

  case Spades = ‚S‘;

}

(Quelle PHP Wiki)

Wichtig: Ein Backed Enum kann entweder den Typ „int“ oder den Typ „string“ enthalten, beides ist innerhalb eines Enums nicht möglich.

Fibers

Mit der PHP-Klasse Fibers kannst du ausgewählte Teile deines Programmes isoliert starten, anhalten oder beenden. Mit „/Fiber“ ist die Implementierung einer Fiber möglich, also eines Codeblockes, der über einen eigenen Stack verfügt.

Du startest eine Fiber über den Main-Thread, dabei kann er bei der Ausführung nicht von diesem unterbrochen werden. Wurde eine Fiber angehalten oder beendet, dann kann ihr Neustart ebenfalls nur über den Main-Thread initiiert werden.

Fibers sind hauptsächlich für Framework-Entwickler gedacht, die eine Low-Level-Schnittstelle benötigen.

Final Class Constants

Mit PHP 8.1 kannst du nun auch Klassen- und Schnittstellenkonstanten mit „final“ markieren. Hast du Konstanten mit „final“ gekennzeichnet, so können sie nicht mehr von Unterklassen erweitert oder überschrieben werden.

class Foo

{

    final public const X = „foo“;

}

// PHP Fatal error:  Bar::X cannot override final constant Foo::X

class Bar extends Foo

{

    public const X = „bar“;

}

(Quelle PHP Wiki)

never Return Type

Ein neuer Return-Typ hält mit „never“ Einzug in die PHP-Welt. Dieses Keyword gibt an, dass die entsprechende Funktion niemals ein Wert zurückgeben wird. Anstelle einer regulären Beendigung der Funktion wird eine Ausnahme ausgelöst oder ein Call-Exit beendet das Programm.

function redirect(string $url): never {

    header(‚Location: ‚ . $url);

    exit();

}

function redirectToLoginPage(): never {

    redirect(‚/login‘);

    echo ‚Hello‘; // <- dead code detected by static analysis

}

(Quelle: php.net

Wenn dir „never“ etwas bekannt vorkommen sollte, dann denkst du sicher an „void“, der ebenfalls die Rückgabe eines Wertes blockiert. „Never“ geht allerdings noch einen Schritt weiter und beendet das Programm im Gegensatz zu „void“. Bei Letzterem führt PHP die nächste Anweisung aus.

Readonly Properties

Ab sofort kannst du mit PHP Klasseneigenschaften als schreibgeschützt kennzeichnen. Dann kann ein Attribut die Eigenschaft „readonly“ haben. Kennzeichen musst du das bei der jeweiligen Eigenschaft in einer Klasse, die du als schreibgeschützt deklarieren möchtest.

class Test {

    public readonly string $prop;

    public function __construct(string $prop) {

        $this->prop = $prop;

    }

}

(Quelle PHP Wiki)

Weitere Änderungen, auf die wir an dieser Stelle nicht explizit eingehen:

  • Mit New In Initializers kannst du neue Schlüsselwörter als Standardparameter in Funktionsdefinitionen und an weiteren Stellen verwenden.
  • Pure Intersection Types – ähnlich den in PHP 8.0 eingeführten Union Types  – sind vor allem  bei Anwendungen, die mit vielen Schnittstellen interagieren, recht hilfreich.
  • Die neue First-Class Callable Syntax vereinfacht dir die Erstellung von Callables mit derselben Syntax, so dass Methoden und Funktionen aufgerufen werden können.
  • Array-Unpacking kannst du jetzt auch mit string-Keys umsetzen.
  • Die GD-Erweiterung in PHP 8.1 bietet dir Unterstützung für das AVIF-Bildformat. Vor der Verwendung muss GD zunächst mit der AVIF-Unterstützung kompiliert werden.
  • Die Option, den FPM-Status im openmetrics-Format darzustellen, so dass Monitoring-Tools wie Prometheus einfacher angebunden werden können.

Alle neuen Features mit PHP 8.1 findest du bei PHP Wiki  

Wichtig: Aktuelle PHP-Version verwenden

Immer wichtig: Du solltest stets eine aktuelle PHP-Version nutzen. Wenn du noch PHP 7.2 oder 7.3 im Einsatz hast, dann update schleunigst, denn beide Versionen werden nicht mehr mit Sicherheitsupdates versorgt. Außerdem sind die neuesten Versionen schneller, sicherer und ressourcenschonender als die vorherigen. Überprüfe aber vor dem Update, ob deine Anwendung auch mit der neueren PHP-Version kompatibel ist und erstell ein Backup, auf dass du im Zweifel zurückgreifen kannst.

Du solltest deinen Code generell aktuell halten, um einerseits neue Funktionen nutzen zu können und andererseits von Performancesteigerungen zu profitieren. Auch die Sicherheitsaspekte solltest du nicht vernachlässigen, da mit den aktuellen Versionen auch Sicherheitslücken geschlossen werden.

Du bist noch auf der Suche nach dem perfekten Hosting für dich?

Dann schau einmal hier vorbei: Wir bieten dir bei checkdomain schnelles und sicheres Hosting auf einer ISO-zertifizierten Webhosting-Plattform.