PHP 8.5 ist da!

PHP 8.5 ist seit ein paar Tagen draußen, und mit ihm eine Handvoll kleiner Neuerungen!
Fokus auf 2 der Features, auf die ich mich am meisten gefreut habe.


1. Der Pipe-Operator |>: mein persönlicher Favorit

PHP 8.5 führt den Pipe-Operator (|>) ein, mit dem sich Callables von oben nach unten verketten lassen.

Vor PHP 8.5

$slug = urlencode(
    trim(
        strtolower($title)
    )
);
$slug = urlencode(
    preg_replace('/\s+/', '-',
        trim(
            strtolower($title)
        )
    )
);

Mit PHP 8.5

$slug = $title
|> strtolower(...)                  // Kleinbuchstaben
|> trim(...)                        // Leerzeichen am Anfang/Ende entfernen
|> urlencode(...);                  // finale URL-Kodierung

Das ist schon deutlich lesbarer!

Es gibt trotzdem ein paar Grenzen:

  • Callables dürfen nur einen Pflichtparameter haben
  • Callables müssen einen Wert zurückgeben
  • der Rückgabewert jeder Pipe ist die Eingabe der nächsten

Das hier zum Beispiel funktioniert nicht:

$slug = $title
|> strtolower(...)                  
|> trim(...)                        
|> preg_replace('/\s+/', '-', ...)  // geht nicht: mehr als ein Pflichtparameter
|> urlencode(...);

Keine Panik! Pipe akzeptiert jeden Callable-Typ, erinnerst du dich?

$slug = $title
|> strtolower(...)                  
|> trim(...)                        
|> (fn(string $subject): string => preg_replace('/\s+/', '-', $subject))  // das geht: ein Parameter, ein Rückgabewert
|> urlencode(...);

Damit lassen sich ziemlich nette Sachen bauen. Stell dir vor: du holst eine Bilderliste, willst die mit einem bestimmten Tag rausfiltern und zählen.
Das sähe so aus (für das Beispiel nehmen wir an, wir bekommen immer alle Bilder zurück):

$count = count(
    array_filter(
        $imageRepository->find(),
        fn(Image $img): bool => $img->hasTag('tag')
    )
);

Mit Pipe:

$count = $imageRepository->find()
|> (fn(array $images) => array_filter($images, fn(Image $img): bool => $img->hasTag('tag')))
|> count(...);

Objekt- / Datenverarbeitungsbeispiel

Noch ein letztes Beispiel für unterwegs:

$user
|> loadProfile(...)       // lädt das vollständige Profil
|> enrichProfile(...)     // fügt berechnete Daten hinzu oder was du willst
|> json_encode(...);      // macht JSON draus

Endlich Schluss mit unlesbaren Verschachtelungen!


2. array_first() und array_last()

Diese beiden — ich habe nie wirklich verstanden, warum wir sie nicht früher bekommen haben. Bisher musste man über reset() und end() gehen, um das erste oder letzte Element zu holen, aber das hat den internen Pointer verändert.
Man konnte auch mit array_key_first() und array_key_last() spielen, aber das war ziemlich wortreich.

$last = $array[array_key_last($array)]; // hat den Pointer nicht angefasst  
$last = end($array);                    // hat den Pointer angefasst

$first = $array[array_key_first($array)]; // hat den Pointer nicht angefasst  
$first = reset($array);                   // hat den Pointer angefasst

Jetzt haben wir endlich das einfache Gegenstück zu array_key_first() und array_key_last():

$latest = array_last($notifications);   // das letzte Element  
$oldest = array_first($notifications);  // das erste

Wichtig: es wird der Wert des Elements zurückgegeben.

$array = ['foo' => 1, 'bar' => 2];  
array_last($array); // gibt 2 zurück  
array_first($array); // gibt 1 zurück

3. Weitere Ergänzungen

Weitere Ergänzungen kommen mit PHP 8.5, weniger spektakulär:

  • Zwei neue Getter helfen beim Debuggen: get_exception_handler() und get_error_handler(). Nichts Besonderes dazu; mehr Infos in der PHP-Watch-Doku .
  • locale_is_right_to_left(): erkennt Locales von rechts nach links. Praktisch für die Internationalisierung. Mehr erfahren
  • curl_multi_get_handles(): holt die Handles eines Multi-Handles. Mehr erfahren
  • Neue Konstante PHP_BUILD_DATE: gibt das Kompilierdatum. Mehr erfahren
  • Neue CLI-Option php --ini=diff: zeigt nur INI-Direktiven, die nicht dem Default entsprechen. Mehr erfahren