PHP 8.2 baut auf der erneuerten Basis von PHP 8.0 und PHP 8.1 auf. Jetzt, wo PHP 8.2 veröffentlicht wurde, wollen wir uns die Neuerungen in PHP 8.2 im Detail ansehen – von den neuen Funktionen und Verbesserungen bis hin zu Verwerfungen und kleineren Änderungen gehen wir alles durch.

Da PHP 8.2 am 19. Juli 2022 eingefroren wurde, sind in dieser Liste keine wesentlichen Neuerungen zu erwarten.

Aufgeregt? Wir sind es auch.

Los geht’s!

Neue Funktionen und Verbesserungen in PHP 8.2

Beginnen wir damit, alle neuen Funktionen von PHP 8.2 kennenzulernen. Die Liste ist ziemlich umfangreich:

Neue readonly Klassen

Mit PHP 8.1 wurde die Funktionreadonly für Klasseneigenschaften eingeführt. Mit PHP 8.2 wird nun die Möglichkeit hinzugefügt, die gesamte Klasse als readonly zu deklarieren.

Wenn du eine Klasse als readonly deklarierst, erben alle ihre Eigenschaften automatisch das readonly Merkmal. Wenn du also eine Klasse readonly deklarierst, ist es dasselbe, als wenn du jede Klasseneigenschaft als readonly deklarierst.

Mit PHP 8.1 musstest du zum Beispiel diesen mühsamen Code schreiben, um alle Klasseneigenschaften als readonly zu deklarieren:

class MyClass
{
public readonly string $myValue,
public readonly int $myOtherValue
public readonly string $myAnotherValue
public readonly int $myYetAnotherValue
}

Stell dir das Gleiche mit vielen weiteren Eigenschaften vor. Jetzt, mit PHP 8.2, kannst du einfach Folgendes schreiben:

readonly class MyClass
{
public string $myValue,
public int $myOtherValue
public string $myAnotherValue
public int $myYetAnotherValue
}

Du kannst auch abstrakte oder finale Klassen als readonly deklarieren. Dabei spielt die Reihenfolge der Schlüsselwörter keine Rolle.

abstract readonly class Free {}
final readonly class Dom {}

Du kannst auch eine readonly Klasse ohne Eigenschaften deklarieren. Dadurch werden dynamische Eigenschaften verhindert, während die untergeordneten Klassen ihre readonly Eigenschaften explizit deklarieren können.

Als Nächstes können readonly Klassen nur typisierte Eigenschaften enthalten – die gleiche Regel gilt für die Deklaration einzelner schreibgeschützter Eigenschaften.

Du kannst die mixed type-Eigenschaft verwenden, wenn du keine streng typisierte Eigenschaft deklarieren kannst.

Der Versuch, eine readonly Klasse ohne typisierte Eigenschaft zu deklarieren, führt zu einem fatalen Fehler:

readonly class Type {
    public $nope;
}
Fatal error: Readonly property Type::$nope must have type in ... on line ... 

Außerdem kannst du readonly nicht für bestimmte PHP-Funktionen deklarieren:

Der Versuch, eine dieser Funktionen als readonly zu deklarieren, führt zu einem Parse-Fehler.

readonly interface Destiny {}
Parse error: syntax error, unexpected token "interface", expecting "abstract" or "final" or "readonly" or "class" in ... on line ...

Wie bei allen PHP-Schlüsselwörtern ist auch beim Schlüsselwort readonly die Groß- und Kleinschreibung egal.

Mit PHP 8.2 werden auch dynamische Eigenschaften verworfen (mehr dazu später). Du kannst jedoch nicht verhindern, dass dynamische Eigenschaften zu einer Klasse hinzugefügt werden. Wenn du dies jedoch für eine Klasse readonly tust, führt das nur zu einem Fatal Error.

Fatal error: Readonly property Test::$test must have type in ... on line ...

true, false, und null als eigenständige Typen zulassen

PHP enthält bereits skalare Typen wie int, string und bool. Diese wurden in PHP 8.0 um Union-Typen erweitert, die es ermöglichen, dass Werte von verschiedenen Typen sein können. Der gleiche RFC erlaubte auch die Verwendung von false und null als Teil eines Union-Typs – als eigenständige Typen waren sie jedoch nicht erlaubt.

Wenn du versucht hast, false oder null als eigenständige Typen zu deklarieren – ohne dass sie Teil eines Union-Typs sind -, kam es zu einem fatalen Fehler.

function spam(): null {}
function eggs(): false {}

Fatal error: Null can not be used as a standalone type in ... on line ...
Fatal error: False can not be used as a standalone type in ... on line ...

Um dieses Szenario zu vermeiden, unterstützt PHP 8.2 nun die Verwendung von false und null als eigenständige Typen. Damit wird das PHP-Typensystem noch aussagekräftiger und vollständiger. Du kannst nun Rückgabe-, Parameter- und Eigenschaftstypen genau deklarieren.

Außerdem gab es in PHP immer noch keinen Typ true, der ein natürliches Gegenstück zum Typ false zu sein schien. PHP 8.2 behebt dies und unterstützt auch den Typ true . Er erlaubt keinen Zwang, genau wie der Typ false.

Die beiden Typen true und false sind im Wesentlichen ein Unionstyp des PHP-Typs bool. Um Redundanz zu vermeiden, kannst du diese drei Typen nicht zusammen in einem Unionstyp deklarieren. Wenn du das tust, führt das zu einem fatalen Kompilierfehler.

Disjunctive Normal Form (DNF) Typen

Die disjunktive Normalform (DNF) ist eine standardisierte Methode, um boolesche Ausdrücke zu organisieren. Sie besteht aus einer Disjunktion von Konjunktionen – in booleschen Begriffen ist das ein ODER von UNDs.

Die Anwendung von DNF auf Typendeklarationen ermöglicht eine standardisierte Art und Weise, kombinierte Union- und Intersection-Typen zu schreiben, die der Parser verarbeiten kann. Die neue DNF-Typenfunktion von PHP 8.2 ist einfach, aber mächtig, wenn sie richtig eingesetzt wird.

Der RFC gibt das folgende Beispiel. Es geht davon aus, dass die folgenden Schnittstellen- und Klassendefinitionen bereits existieren:

interface A {}
interface B {}
interface C extends A {}
interface D {}

class W implements A {}
class X implements B {}
class Y implements A, B {}
class Z extends Y implements C {}

Mit DNF-Typen kannst du Typdeklarationen für Eigenschaften, Parameter und Rückgabewerte wie folgt vornehmen:

// Accepts an object that implements both A and B,
// OR an object that implements D
(A&B)|D

// Accepts an object that implements C, 
// OR a child of X that also implements D,
// OR null
C|(X&D)|null

// Accepts an object that implements all three of A, B, and D, 
// OR an int, 
// OR null.
(A&B&D)|int|null

In manchen Fällen können die Eigenschaften nicht in DNF-Form vorliegen. Wenn du sie als solche deklarierst, führt das zu einem Parse-Fehler. Du kannst sie aber jederzeit umschreiben als:

A&(B|D)
// Can be rewritten as (A&B)|(A&D)

A|(B&(D|W)|null)
// Can be rewritten as A|(B&D)|(B&W)|null

Du solltest beachten, dass jedes Segment eines DNF-Typs eindeutig sein muss. So ist zum Beispiel die Deklaration (A&B)|(B&A) ungültig, da die beiden ODER-verknüpften Segmente logisch gleich sind.

Außerdem sind Segmente, die strenge Teilmengen des anderen Segments sind, ebenfalls nicht zulässig. Das liegt daran, dass die Obermenge bereits alle Instanzen der Untermenge enthält, so dass es überflüssig ist, DNF zu verwenden.

Sensible Parameter in Backtraces redacten

Wie fast jede Programmiersprache erlaubt auch PHP die Nachverfolgung des Aufrufstapels an jedem Punkt der Codeausführung. Das Stack-Tracing erleichtert das Debuggen von Code, um Fehler und Leistungsengpässe zu beheben. Es bildet das Rückgrat von Tools wie Kinsta APM, unserem maßgeschneiderten Performance-Monitoring-Tool für WordPress-Sites.

Langsame WooCommerce-Transaktionen mit Kinsta APM aufspüren
Langsame WooCommerce-Transaktionen mit Kinsta APM aufspüren

Wenn du einen Stack Trace durchführst, hältst du die Ausführung des Programms nicht an. Normalerweise laufen die meisten Stack Traces im Hintergrund und werden stillschweigend protokolliert – für eine spätere Überprüfung, falls nötig.

Einige dieser detaillierten PHP-Stacktraces können jedoch von Nachteil sein, wenn du sie an Drittanbieterdienste weitergibst – in der Regel für die Analyse von Fehlerprotokollen, die Fehlerverfolgung usw. Diese Stack Traces können sensible Informationen wie Benutzernamen, Passwörter und Umgebungsvariablen enthalten.

Dieser RFC-Vorschlag gibt ein solches Beispiel:

Ein häufiger „Übeltäter“ ist PDO, das das Datenbankpasswort als Konstruktorparameter annimmt und sofort versucht, sich innerhalb des Konstruktors mit der Datenbank zu verbinden, anstatt einen reinen Konstruktor und eine separate ->connect() Methode zu haben. Wenn die Datenbankverbindung fehlschlägt, enthält der Stack-Trace das Datenbankpasswort:

PDOException: SQLSTATE[HY000] [2002] No such file or directory in /var/www/html/test.php:3
Stack trace: #0 /var/www/html/test.php(3): PDO->__construct('mysql:host=loca...', 'root', 'password')
#1 {main}

Mit PHP 8.2 kannst du solche sensiblen Parameter mit dem neuen Attribut \SensitiveParameter kennzeichnen. Jeder Parameter, der als sensibel gekennzeichnet ist, wird in deinen Backtraces nicht aufgeführt. So kannst du sie bedenkenlos an Drittanbieterdienste weitergeben.

Hier ist ein einfaches Beispiel mit einem einzigen sensiblen Parameter:

<?php

function example(
    $ham,
    #[\SensitiveParameter] $eggs,
    $butter
) {
    throw new \Exception('Error');
}

example('ham', 'eggs', 'butter');

/*
Fatal error: Uncaught Exception: Error in test.php:8
Stack trace:
#0 test.php(11): test('ham', Object(SensitiveParameterValue), 'butter')
#1 {main}
thrown in test.php on line 8
*/

Wenn du einen Backtrace erstellst, wird jeder Parameter mit dem Attribut \SensitiveParameter durch ein \SensitiveParameterValue Objekt ersetzt, und sein tatsächlicher Wert wird nie im Trace gespeichert. Das SensitiveParameterValue Objekt kapselt den tatsächlichen Parameterwert ein – falls du ihn aus irgendeinem Grund benötigst.

Neue mysqli_execute_query Funktion und mysqli::execute_query Methode

Hast du jemals die Funktion mysqli_query() mit gefährlich ausbrechenden Benutzerwerten verwendet, nur um eine parametrisierte MySQLi-Abfrage auszuführen?

PHP 8.2 macht das Ausführen von parametrisierten MySQLi-Abfragen mit der neuen Funktion mysqli_execute_query($sql, $params) und der Methode mysqli::execute_query einfacher.

Im Wesentlichen ist diese neue Funktion eine Kombination aus den Funktionen mysqli_prepare(), mysqli_execute() und mysqli_stmt_get_result(). Mit ihr wird die MySQLi-Abfrage vorbereitet, gebunden (falls du Parameter übergeben hast) und innerhalb der Funktion selbst ausgeführt. Wenn die Abfrage erfolgreich ausgeführt wird, gibt sie ein mysqli_result Objekt zurück. Wenn sie nicht erfolgreich war, wird false zurückgegeben.

Der RFC-Vorschlag enthält ein einfaches, aber aussagekräftiges Beispiel:

foreach ($db->execute_query('SELECT * FROM user WHERE name LIKE ? AND type_id IN (?, ?)', [$name, $type1, $type2]) as $row) {
print_r($row);
}

Abrufen von enum Eigenschaften in const Ausdrücken

Dieser RFC schlägt vor dem ->/?-> Operator zu erlauben enum Eigenschaften in const Ausdrücken abzurufen.

Der Hauptgrund für diese neue Funktion ist, dass du enum Objekte an einigen Stellen nicht verwenden kannst, z. B. bei Array-Schlüsseln. In einem solchen Fall musst du den Wert des enum Falls wiederholen, um ihn zu verwenden.

Das Abrufen von enum Eigenschaften an Stellen, an denen enum Objekte nicht erlaubt sind, kann dieses Verfahren vereinfachen.

Das bedeutet, dass der folgende Code jetzt gültig ist:

const C = [self::B->value => self::B];

Und um auf Nummer sicher zu gehen, enthält dieser RFC auch Unterstützung für den Nullsafe-Operator ?->.

Konstanten in Traits zulassen

PHP bietet eine Möglichkeit zur Wiederverwendung von Code, die Traits. Sie sind ideal für die Wiederverwendung von Code in verschiedenen Klassen.

Derzeit können in Traits nur Methoden und Eigenschaften, aber keine Konstanten definiert werden. Das bedeutet, dass du keine Invarianten, die von einem Trait erwartet werden, innerhalb des Traits selbst definieren kannst. Um diese Einschränkung zu umgehen, musst du Konstanten in der komponierenden Klasse oder in einer Schnittstelle definieren, die von der komponierenden Klasse implementiert wird.

In diesem RFC wird vorgeschlagen, die Definition von Konstanten in Traits zu ermöglichen. Diese Konstanten können genauso definiert werden, wie du Klassen-Konstanten definieren würdest. Dieses Beispiel, das direkt aus dem RFC entnommen wurde, verdeutlicht die Verwendung der Konstanten:

trait Foo {
    public const FLAG_1 = 1;
    protected const FLAG_2 = 2;
    private const FLAG_3 = 2;

    public function doFoo(int $flags): void {
        if ($flags & self::FLAG_1) {
            echo 'Got flag 1';
        }
        if ($flags & self::FLAG_2) {
            echo 'Got flag 2';
        }
        if ($flags & self::FLAG_3) {
        echo 'Got flag 3';
        }
    }
}

Trait-Konstanten werden in die Definition der zusammensetzenden Klasse integriert, genau wie die Definitionen der Eigenschaften und Methoden eines Traits. Sie haben auch ähnliche Einschränkungen wie die Eigenschaften von Traits. Wie im RFC erwähnt, ist dieser Vorschlag zwar ein guter Anfang, muss aber noch weiter ausgearbeitet werden, um die Funktion zu vervollständigen.

Verwerfungen in PHP 8.2

Jetzt können wir uns mit den Verwerfungen in PHP 8.2 befassen. Die Liste ist nicht ganz so umfangreich wie die der neuen Funktionen:

Veraltete dynamische Eigenschaften (und das neue Attribut #[AllowDynamicProperties] )

Bis zu PHP 8.1 konntest du in PHP nicht deklarierte Klasseneigenschaften dynamisch setzen und abrufen. Zum Beispiel:

class Post {
    private int $pid;
}

$post = new Post();
$post->name = 'Kinsta';

Hier deklariert die Klasse Post keine Eigenschaft name. Da PHP aber dynamische Eigenschaften erlaubt, kannst du sie außerhalb der Klassendeklaration setzen. Das ist der größte – und vielleicht auch einzige – Vorteil der Klasse.

Mit dynamischen Eigenschaften können unerwartete Fehler und Verhaltensweisen in deinem Code auftauchen. Wenn du zum Beispiel bei der Deklaration einer Klasseneigenschaft außerhalb der Klasse einen Fehler machst, kannst du sie leicht aus den Augen verlieren – vor allem bei der Fehlersuche innerhalb der Klasse.

Ab PHP 8.2 sind dynamische Eigenschaften veraltet. Wenn du einer nicht deklarierten Klasseneigenschaft einen Wert zuweist, wird beim ersten Setzen der Eigenschaft ein Hinweis auf die Verwerfung ausgegeben.

class Foo {}
$foo = new Foo;

// Deprecated: Creation of dynamic property Foo::$bar is deprecated
$foo->bar = 1;

// No deprecation warning: Dynamic property already exists.
$foo->bar = 2;

Ab PHP 9.0 wird beim Setzen einer solchen Eigenschaft jedoch ein ErrorException Fehler ausgegeben.

Wenn dein Code voller dynamischer Eigenschaften ist – und das ist in vielen PHP-Codes der Fall – und wenn du diese Verfallsmeldungen nach dem Upgrade auf PHP 8.2 vermeiden willst, kannst du das neue Attribut #[AllowDynamicProperties] von PHP 8.2 verwenden, um dynamische Eigenschaften für Klassen zuzulassen.

#[AllowDynamicProperties]
class Pets {}
class Cats extends Pets {}

// You'll get no deprecation warning
$obj = new Pets;
$obj->test = 1;

// You'll get no deprecation warning for child classes
$obj = new Cats;
$obj->test = 1;

Laut RFC können Klassen, die als #[AllowDynamicProperties] gekennzeichnet sind, sowie ihre Unterklassen weiterhin dynamische Eigenschaften verwenden, ohne dass sie veraltet sind oder entfernt werden.

Du solltest auch beachten, dass in PHP 8.2 die einzige gebündelte Klasse, die als #[AllowDynamicProperties] gekennzeichnet ist, stdClass ist. Außerdem gelten alle Eigenschaften, auf die über die PHP-Magic-Methoden __get() oder __set() zugegriffen wird, nicht als dynamische Eigenschaften, so dass sie keinen Hinweis auf die Veralterung auslösen.

Teilweise unterstützte Callables verwerfen

Eine weitere Änderung in PHP 8.2, wenn auch mit geringeren Auswirkungen, ist die Abschaffung von teilweise unterstützten Callables.

Diese Callables werden als teilweise unterstützt bezeichnet, weil du sie nicht direkt über $callable() ansprechen kannst. Du kannst sie nur über die Funktion call_user_func($callable) erreichen. Die Liste solcher Callables ist nicht lang:

"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]

Ab PHP 8.2 wird jeder Versuch, solche Callables aufzurufen – z. B. über die Funktionen call_user_func() oder array_map() – eine Deprecation-Warnung auslösen.

Der ursprüngliche RFC liefert eine solide Begründung für diese Verwerfung:

Abgesehen von den letzten beiden Fällen sind alle diese Callables kontextabhängig. Die Methode, auf die sich "self::method" bezieht, hängt davon ab, von welcher Klasse aus der Aufruf oder die Prüfung der Aufrufbarkeit durchgeführt wird. In der Praxis gilt dies in der Regel auch für die letzten beiden Fälle, wenn sie in der Form von [new Foo, "parent::method"] verwendet werden.

Die Verringerung der Kontextabhängigkeit von Callables ist das zweite Ziel dieses RFC. Nach diesem RFC bleibt nur noch die Sichtbarkeit von Methoden übrig: "Foo::bar" kann in einem Bereich sichtbar sein, in einem anderen aber nicht. Wenn Callables in Zukunft auf öffentliche Methoden beschränkt würden (während private Methoden Callables erster Klasse oder Closure::fromCallable() verwenden müssten, um scope-unabhängig zu sein), dann wäre der Callable-Typ klar definiert und könnte als Eigenschaftstyp verwendet werden.Änderungen an der Handhabung der Sichtbarkeit werden in diesem RFC jedoch nicht vorgeschlagen

.
Wie im ursprünglichen RFC vorgesehen, werden die Funktion is_callable() und der Typ callable diese Callables weiterhin als Ausnahmen akzeptieren. Allerdings nur so lange, bis die Unterstützung für sie ab PHP 9.0 vollständig entfernt wird.

Um Verwirrung zu vermeiden, wurde der Geltungsbereich der Verwerfungsmitteilung mit einem neuen RFC erweitert – er umfasst nun auch diese Ausnahmen.

Es ist gut zu sehen, dass sich PHP in Richtung eines klar definierten callable Typs bewegt.

Ablehnung der Funktionen #utf8_encode() und utf8_decode()

Die in PHP eingebauten Funktionen utf8_encode() und utf8_decode() konvertieren Strings, die in ISO-8859-1 („Latin 1“) kodiert sind, in und aus UTF-8.

Ihre Namen deuten jedoch auf eine allgemeinere Verwendung hin, als ihre Implementierung zulässt. Die Kodierung „Latin 1“ wird häufig mit anderen Kodierungen wie der „Windows Code Page 1252“ verwechselt

Außerdem siehst du in der Regel Mojibake, wenn diese Funktionen einen String nicht richtig umwandeln können. Das Fehlen von Fehlermeldungen bedeutet auch, dass es schwierig ist, sie zu erkennen, besonders in einem Meer von ansonsten lesbarem Text.

In PHP 8.2 sind die Funktionen #utf8_encode() und utf8_decode() veraltet. Wenn du sie aufrufst, siehst du diese Hinweise zur Veraltung:

Deprecated: Function utf8_encode() is deprecated
Deprecated: Function utf8_decode() is deprecated

Der RFC empfiehlt, stattdessen die von PHP unterstützten Erweiterungen wie mbstring, iconv und intl zu verwenden.

Verwerfung der ${} String-Interpolation

PHP erlaubt das Einbetten von Variablen in Strings mit doppelten Anführungszeichen (") und heredoc (<<<) auf verschiedene Weise:

  1. Direktes Einbetten von Variablen – “$foo”
  2. Mit geschweiften Klammern außerhalb der Variablen – “{$foo}”
  3. Mit geschweiften Klammern nach dem Dollarzeichen – “${foo}”
  4. Variable Variablen – “${expr}” – entspricht der Verwendung von (string) ${expr}

Die ersten beiden Möglichkeiten haben ihre Vor- und Nachteile, während die beiden letzteren eine komplexe und widersprüchliche Syntax haben. Mit PHP 8.2 werden die letzten beiden Möglichkeiten der Stringeinbettung veraltet.

Du solltest in Zukunft keine Strings mehr auf diese Weise interpolieren:

"Hello, ${world}!";
Deprecated: Using ${} in strings is deprecated

"Hello, ${(world)}!";
Deprecated: Using ${} (variable variables) in strings is deprecated

Ab PHP 9.0 werden diese veralteten Methoden aktualisiert und führen zu einem Ausnahmefehler.

Verwerfung der mbstring-Funktionen für Base64/QPrint/Uuencode/HTML-Entities

Die mbstring-Funktionen (Multi-Byte-String) von PHP helfen uns bei der Arbeit mit Unicode, HTML-Entities und anderen alten Textkodierungen.

Base64, Uuencode und QPrint sind jedoch keine Textkodierungen und sind trotzdem Teil dieser Funktionen – vor allem aus Legacy-Gründen. PHP enthält auch separate Implementierungen dieser Kodierungen.

Für HTML-Entities gibt es in PHP integrierte Funktionen – htmlspecialchars() und htmlentities() -, die besser mit ihnen umgehen können. Im Gegensatz zu mbstring wandeln diese Funktionen zum Beispiel auch <. >. und & in HTML-Entities um.

Außerdem verbessert PHP seine eingebauten Funktionen ständig – so wie PHP 8.1 mit den Funktionen zur HTML-Kodierung und -Dekodierung.

Aus diesem Grund wird in PHP 8.2 die Verwendung von mbstring für diese Kodierungen nicht mehr empfohlen (Groß- und Kleinschreibung wird nicht beachtet):

  • BASE64
  • UUENCODE
  • HTML-ENTITIES
  • html (Alias von HTML-ENTITIES)
  • Quoted-Printable
  • qprint (alias von Quoted-Printable)

Ab PHP 8.2 wird die Verwendung von mbstring zur Kodierung/Dekodierung einer der oben genannten Kodierungen einen Verwerfungshinweis ausgeben. Mit PHP 9.0 wird die mbstring-Unterstützung für diese Kodierungen komplett entfernt.

Andere kleinere Änderungen in PHP 8.2

Abschließend können wir die kleineren Änderungen in PHP 8.2 besprechen, einschließlich der entfernten Features und Funktionalitäten.

Unterstützung für libmysql von mysqli entfernen

Zurzeit erlaubt PHP den Treibern mysqli und PDO_mysql, gegen die Bibliotheken mysqlnd und libmysql zu bauen. Der Standardtreiber, der seit PHP 5.4 empfohlen wird, ist jedoch mysqlnd.

Diese beiden Treiber haben viele Vor- und Nachteile. Wenn du jedoch die Unterstützung für einen der beiden Treiber entfernst – idealerweise libmysql, da es nicht der Standardtreiber ist -, vereinfachst du den PHP-Code und die Unit-Tests.

Um ein Argument dafür zu finden, listet der RFC viele Vorteile von mysqlnd auf:

  • Es ist mit PHP gebündelt
  • Es nutzt die PHP-Speicherverwaltung, um die Speichernutzung zu überwachen und
    Performance zu verbessern
  • Bietet Quality-of-Life-Funktionen (z. B. get_result())
  • Gibt numerische Werte mit PHP-eigenen Typen zurück
  • Die Funktionalität ist nicht von einer externen Bibliothek abhängig
  • Optionale Plugin-Funktionalität
  • Unterstützt asynchrone Abfragen

Der RFC listet auch einige Vorteile von libmysql auf, darunter:

Darüber hinaus listet der RFC viele Nachteile von libmysql auf – Inkompatibilität mit dem PHP-Speichermodell, viele fehlgeschlagene Tests, Speicherlecks, unterschiedliche Funktionalitäten zwischen den Versionen usw.

Vor diesem Hintergrund wurde mit PHP 8.2 die Unterstützung für die Erstellung von mysqli gegen libmysql entfernt.

Wenn du eine Funktion hinzufügen möchtest, die nur mit libmysql verfügbar ist, musst du sie explizit als Feature Request zu mysqlnd hinzufügen. Außerdem kannst du keine automatische Verbindungswiederherstellung hinzufügen.

Lokal-unabhängige Fallkonvertierung

Vor PHP 8.0 wurde das Gebietsschema von PHP von der Systemumgebung geerbt. Dies konnte jedoch in einigen Fällen zu Problemen führen.

Wenn du deine Sprache bei der Installation von Linux einstellst, wird die entsprechende Sprache der Benutzeroberfläche für die eingebauten Befehle eingestellt. Allerdings ändert sich dadurch auch unerwartet die Art und Weise, wie die String-Bearbeitung der C-Bibliothek funktioniert.

Wenn du zum Beispiel bei der Installation von Linux die Sprache „Türkisch“ oder „Kasachisch“ ausgewählt hast, wirst du feststellen, dass der Aufruf von toupper('i'), um das Äquivalent in Großbuchstaben zu erhalten, das gepunktete große I (U+0130, İ) ergibt.

Mit PHP 8.0 wurde diese Anomalie beseitigt, indem das Standard-Locale auf „C“ gesetzt wurde, es sei denn, der Benutzer ändert es ausdrücklich über setlocale().

PHP 8.2 geht sogar noch einen Schritt weiter, indem es die Groß- und Kleinschreibung nicht mehr von der Locale abängig macht. Dieser RFC ändert vor allem strtolower(), strtoupper() und verwandte Funktionen. Im RFC findest du eine Liste aller betroffenen Funktionen.

Wenn du die lokalisierte Groß- und Kleinschreibung verwenden möchtest, kannst du alternativ mb_strtolower() verwenden.

Verbesserung der Random Extension

PHP plant, seine Zufallsfunktionalität zu überarbeiten.

Zurzeit basiert die PHP-Zufallsfunktion stark auf dem Mersenne Twister-Status. Dieser Zustand wird jedoch implizit im globalen Bereich von PHP gespeichert – es gibt keine Möglichkeit für den Benutzer, darauf zuzugreifen. Das Hinzufügen von Zufallsfunktionen zwischen der ersten Seeding-Phase und der beabsichtigten Verwendung würde den Code kaputt machen.

Die Pflege eines solchen Codes kann sogar noch komplizierter sein, wenn dein Code externe Pakete verwendet.

Die aktuelle Zufallsfunktion von PHP kann also keine konsistenten Zufallswerte erzeugen. Sie versagt sogar bei empirischen statistischen Tests einheitlicher Zufallszahlengeneratoren, wie Crush und BigCrush von TestU01. Die 32-Bit-Beschränkung von Mersenne Twister verschlimmert das Problem noch weiter.

Daher ist es nicht empfehlenswert, die in PHP eingebauten Funktionen – shuffle(), str_shuffle(), array_rand() – zu verwenden, wenn du kryptografisch sichere Zufallszahlen benötigst. In solchen Fällen musst du eine neue Funktion mit random_int() oder ähnlichen Funktionen implementieren.

Nachdem die Abstimmung begonnen hatte, wurden jedoch mehrere Probleme mit diesem RFC aufgeworfen. Dieser Rückschlag zwang das PHP-Team dazu, alle Probleme in einem separaten RFC festzuhalten und für jedes Problem eine Abstimmungsoption zu erstellen. Erst wenn ein Konsens erreicht ist, wird über das weitere Vorgehen entschieden.

Zusätzliche RFCs in PHP 8.2

PHP 8.2 enthält auch viele neue Funktionen und kleinere Änderungen. Wir erwähnen sie im Folgenden mit Links zu weiteren Ressourcen:

  1. Neue Funktion curl_upkeep: PHP 8.2 fügt diese neue Funktion zu seiner Curl-Erweiterung hinzu. Sie ruft die Funktion curl_easy_upkeep() in libcurl auf, der zugrunde liegenden C-Bibliothek, die die PHP-Curl-Erweiterung nutzt.
  2. Neue Funktion ini_parse_quantity: PHP INI-Direktiven akzeptieren Datengrößen mit einem Multiplikator-Suffix. Du kannst zum Beispiel 25 Megabyte als 25M oder 42 Gigabyte als 42G schreiben. Diese Suffixe sind in PHP-INI-Dateien üblich, aber in anderen Dateien eher unüblich. Diese neue Funktion parst die PHP INI-Werte und gibt ihre Datengröße in Bytes zurück.
  3. Neue Funktion memory_reset_peak_usage: Diese Funktion setzt die von der Funktion memory_get_peak_usage zurückgegebene maximale Speichernutzung zurück. Das kann praktisch sein, wenn du dieselbe Aktion mehrmals ausführst und den maximalen Speicherverbrauch jedes Durchlaufs aufzeichnen möchtest.
  4. Unterstützung für den Modifikator no-capture (/n) in preg_* Funktionen: In Regex kennzeichnen die Metazeichen () eine Fanggruppe. Das bedeutet, dass alle Übereinstimmungen mit dem Ausdruck innerhalb der Klammer zurückgegeben werden. PHP 8.2 fügt einen No-Capture-Modifikator (/n) hinzu, um dieses Verhalten zu unterbinden.
  5. Die iterator_*() Familie muss alle Iterablen akzeptieren: Bisher akzeptiert die iterator_*() Familie von PHP nur \Traversables (d.h. es sind keine einfachen Arrays erlaubt). Das ist eine unnötige Einschränkung, die mit diesem RFC behoben wird.

Zusammenfassung

PHP 8.2 baut auf den massiven Verbesserungen in PHP 8.0 und PHP 8.1 auf, was keine leichte Aufgabe ist. Die spannendsten Funktionen von PHP 8.2 sind unserer Meinung nach die neuen eigenständigen Typen, die schreibgeschützten Eigenschaften und die zahlreichen Leistungsverbesserungen.

Wir können es kaum erwarten, PHP 8.2 mit verschiedenen PHP-Frameworks und CMS zu vergleichen.

Setze ein Lesezeichen für diesen Blog-Beitrag, damit du in Zukunft darauf zurückgreifen kannst.

Welche Funktionen von PHP 8.2 sind deine Favoriten? Welche Fehler sind dir am wenigsten wichtig? Bitte teile deine Meinung mit unserer Community in den Kommentaren!

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.