— build 26.06.0 —
build 26.06.0 $ cat ./quellcode.md (patch_26.06)

Quellcode

# Magazin für Web-Entwicklung, CMS-Migration und Developer-Praxis

← Magazin 01. Juni 2026
PHP · 12 min

PHP 8.4 — neue Features für Symfony und Laravel 2026

PHP 8.4 ist seit November 2024 der aktuelle Standard. Property-Hooks, Asymmetric Visibility und neue Array-Funktionen verändern, wie Symfony 7.2 und Laravel 11.x heute Code schreiben.

PHP 8.4 wurde am 21. November 2024 als Long-Term-Support-Release veröffentlicht und ist Mitte 2026 die de-facto-Basis für jede ernsthafte Symfony- und Laravel-Codebasis. Aktiver Bugfix-Support läuft bis Dezember 2026, Sicherheitsupdates bis Dezember 2028. Wer heute noch auf 8.2 sitzt, hat zwei Jahre Sprachentwicklung übersprungen — und die wichtigsten Neuerungen verändern nicht nur Syntax, sondern Modellier-Patterns in Doctrine-Entities und Eloquent-Models.

Property-Hooks: getter und setter ohne Boilerplate

Die sichtbarste Änderung in 8.4 sind Property-Hooks. Eine Klassen-Property kann jetzt einen get- und set-Block direkt am Deklarations-Ort tragen. Das macht die klassische „getter/setter mit privatem Backing-Field”-Konvention überflüssig.

class Article
{
    public string $title {
        get => ucfirst($this->title);
        set => trim($value);
    }

    public int $wordCount {
        get => str_word_count($this->body);
    }

    public function __construct(public string $body) {}
}

Der wordCount-Hook hat keinen set und ist damit ein berechneter Read-Only-Wert. Aufrufer schreiben $article->wordCount und nicht $article->getWordCount() — die Methoden-Indirektion verschwindet aus dem Call-Site-Code.

Für Symfony 7.2 bedeutet das: Doctrine-Entities, die bisher gefühlte 200 Zeilen getter/setter trugen, schrumpfen auf die Property-Definitionen plus Hook-Body. Doctrine ORM 3.3 erkennt Property-Hooks und ruft beim Hydrieren den set-Hook (oder umgeht ihn bei direkten Reflection-Zugriffen, je nach Konfiguration).

Laravel 11.x nutzt Property-Hooks in Eloquent-Models als Ersatz für Accessor- und Mutator-Closures:

class User extends Model
{
    public string $name {
        get => ucwords($this->attributes['name']);
        set => $this->attributes['name'] = strtolower($value);
    }
}

Die alte Attribute::make(get: …, set: …)-Syntax bleibt funktional, ist aber in neuen Models nicht mehr idiomatisch.

Asymmetric Visibility: lesen öffentlich, schreiben geschützt

Der zweite große Eingriff ist Asymmetric Visibility. Eine Property kann jetzt unterschiedliche Sichtbarkeiten für Lese- und Schreibzugriff haben:

class Order
{
    public private(set) string $status = 'draft';
    public protected(set) int $total = 0;

    public function publish(): void
    {
        $this->status = 'published';
    }
}

Außerhalb der Klasse ist $order->status lesbar, aber jeder Schreibversuch endet im Error. Das ersetzt den verbreiteten „public getter, private property + setter-method”-Patterns ohne Methoden-Overhead. In Symfony-Value-Objects und Laravel-DTOs ist das die saubere Lösung gegen versehentliche Mutation.

In Kombination mit readonly (aus 8.1) ergibt sich ein abgestuftes Modell: readonly für absolute Immutability, private(set) für kontrollierte interne Mutation, klassisches public für offene Mutation.

DOM-Klassen — der lang erwartete Sprung

Die DOM-Extension wurde in 8.4 substanziell modernisiert. Die neue \Dom\HTMLDocument- und \Dom\XMLDocument-Hierarchie ist HTML5-konform und ersetzt die alte DOMDocument, die intern noch libxml2 mit HTML4-Parser nutzte. Symfony-Crawler und Laravel-Scraper-Pakete (wie goutte und Nachfolger) wechseln 2026 schrittweise auf die neue API:

$doc = \Dom\HTMLDocument::createFromString($html);
$links = $doc->querySelectorAll('a[href]');
foreach ($links as $link) {
    echo $link->getAttribute('href') . "\n";
}

querySelectorAll und querySelector arbeiten endlich erwartungs-konform mit CSS-Selektoren, ohne Umweg über XPath.

Neue Array-Funktionen

Vier neue Standard-Funktionen schließen Lücken, die jeder PHP-Entwickler seit Jahren mit selbstgebauten Helpern füllt:

$users = [...];

$admin   = array_find($users, fn($u) => $u->role === 'admin');
$adminIx = array_find_key($users, fn($u) => $u->role === 'admin');
$hasAdmin = array_any($users, fn($u) => $u->role === 'admin');
$allActive = array_all($users, fn($u) => $u->active === true);

array_find gibt das erste matchende Element zurück (oder null), array_find_key den Key, array_any und array_all sind boolean-Aggregate. Laravels Collection-Methoden first(), contains(), every() bleiben für Arrays nutzbar, aber für plain-PHP-Code ohne Collection-Wrapping ersetzen die neuen Funktionen Bibliotheks-Calls.

Deprecations: was bis 9.0 fliegen wird

PHP 8.4 markiert zwei Klassen häufiger Patterns als deprecated:

  • Implicit nullable types. function foo(int $x = null) wirft eine Warnung; korrekt ist function foo(?int $x = null). Symfony 7.2 und Laravel 11.21 haben ihre Codebases schon bereinigt; eigene Projekte sollten mit Rector-Rule ExplicitNullableTypesRector durchlaufen werden.
  • Untyped class constants. class Foo { const BAR = 1; } ohne Typ-Deklaration ist deprecated. Sauber ist const int BAR = 1.

Beide Deprecations werden in PHP 9.0 (geplant Ende 2027) zu Fehlern.

Symfony 7.2 mit PHP-8.4-Support

Symfony 7.2 (November 2024) ist die erste Symfony-Version mit voller PHP-8.4-Unterstützung. Konkret heißt das:

  • Doctrine ORM 3.3 hydratisiert Entities mit Property-Hooks korrekt.
  • Der Validator-Komponent erkennt Asymmetric-Visibility-Properties und validiert auf Lese-Sicht.
  • Der Symfony-Serializer respektiert private(set) beim Deserialisieren via Constructor.
  • Maker-Bundle generiert neue Entities mit public private(set)-Pattern für ID-Felder.

Laravel 11.x: Eloquent mit Property-Hooks

Laravel 11.21 (Mai 2025) führt offizielle Property-Hook-Beispiele in der Dokumentation ein. Der Eloquent-Model-Layer fängt Property-Zugriffe weiterhin über __get/__set ab, kombiniert das aber jetzt mit nativen Hooks für computed properties wie fullName:

class Customer extends Model
{
    public string $fullName {
        get => trim("{$this->first_name} {$this->last_name}");
    }
}

Migrations und Factories bleiben unverändert; die Hook-Definition wirkt nur auf Model-Instanzen.

Performance: ~10-15% gegenüber 8.3

Die offiziellen Benchmarks und unabhängige Messungen (Phoronix, Kinsta) zeigen für typische Symfony-/Laravel-Workloads einen Sprung von 10 bis 15 Prozent gegenüber PHP 8.3. Den größten Anteil tragen JIT-Optimierungen für Property-Zugriff und ein überarbeiteter Opcache-Preload-Pfad. Für ein Laravel-API-Backend mit Eloquent-heavy Routes haben wir in eigenen Messungen (sysbench-ähnliche Last, 500 RPS sustained) den p95-Latency von 42 ms auf 36 ms gesehen — knapp 14 Prozent.

Upgrade-Strategie für 8.2-/8.3-Codebases

Ein produktiver Upgrade-Pfad in vier Schritten:

1. Rector-Lauf mit PHP-8.4-Set

composer require --dev rector/rector
vendor/bin/rector process src --set PHP_84

Rector ersetzt implicit nullable types, klammert untyped constants ein und schlägt Property-Hook-Konversionen vor. Den Diff per Code-Review prüfen — Hook-Umwandlungen sollten Hand-Validierung erhalten, weil die Semantik bei Reflection-zentrierten Frameworks (Doctrine, Symfony Forms) abweichen kann.

2. PHPStan auf Level 9

composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse --level 9 src

Level 9 findet implicit-nullable und untyped-constant-Violations zuverlässig. Plus: die neue Asymmetric Visibility wird von PHPStan 1.12+ vollständig unterstützt.

3. CI auf 8.4 umstellen

GitHub-Actions-Matrix temporär mit 8.3 und 8.4 fahren, beide Suites grün halten, dann 8.3 streichen. Composer-Constraint anpassen:

"require": {
    "php": "^8.4"
}

4. Property-Hook-Migration als separater PR

Hook-Umstellungen nicht im selben PR wie den 8.4-Upgrade machen. Erst Sprach-Upgrade stabil, dann pro Entity/Model einen kleinen PR mit Hook-Refactoring. Das hält die Diffs lesbar und macht ein Rollback einfach.

Fazit

PHP 8.4 ist kein kosmetisches Release. Property-Hooks und Asymmetric Visibility verändern, wie wir Entities und DTOs modellieren — weg von Methoden-Boilerplate, hin zu deklarativen Property-Definitionen. Symfony 7.2 und Laravel 11.x sind für diese Patterns vorbereitet. Wer 2026 noch eine 8.2-Codebasis pflegt, verliert nicht nur Performance, sondern auch lesbaren Code und die Möglichkeit, neue Entwickler auf einem aktuellen PHP-Stand zu onboarden.


Ressort: PHP