Property Hooks, neue Array-Funktionen, DOM-API und mehr auf einen Blick
PHP 8.4 bündelt eine ungewöhnlich hohe Zahl an Sprachfeatures in einem einzigen Release: von Property Hooks über vier neue Array-Funktionen bis zur überarbeiteten DOM-API. Dieser Überblick ordnet jedes der neuen PHP 8.4 Features ein, zeigt echten Code und markiert, was beim Upgrade auf PHP 8.4 tatsächlich brechen kann.
Inhaltsverzeichnis
- 1. Warum PHP 8.4 ein wichtiges Release ist
- 2. Property Hooks im Überblick
- 3. Asymmetric Visibility im Überblick
- 4. Neue Array-Funktionen: array_find, array_any, array_all, array_find_key
- 5. Das #[\Deprecated]-Attribut für eigene APIs
- 6. Neue HTML5-konforme DOM-API
- 7. Objekt-Instanziierung mit direktem Methodenaufruf
- 8. Performance-Verbesserungen und JIT-Anpassungen
- 9. Breaking Changes und Migrationshinweise
- 10. Zusammenfassung
- 11. FAQ
1. Warum PHP 8.4 ein wichtiges Release ist
PHP folgt seit PHP 8.0 einem festen jährlichen Release-Rhythmus: Jedes Jahr im November erscheint eine neue Minor-Version. PHP 8.4 wurde am 21. November 2024 veröffentlicht und reiht sich damit nahtlos in die PHP 8.x-Serie ein, die inzwischen mehrere Jahre Entwicklungsgeschichte umfasst. Jede Version erhält zwei Jahre aktive Unterstützung mit Bugfixes und Sicherheitsupdates, gefolgt von einem weiteren Jahr, in dem ausschließlich kritische Sicherheitslücken geschlossen werden. Für PHP 8.4 heißt das konkret: aktive Unterstützung bis November 2026, Security-Support bis November 2027. Wer produktive Magento- oder Symfony-Projekte betreibt, sollte diesen Zeitrahmen kennen, weil er den Migrationsdruck für die kommenden Jahre bestimmt.
Anders als viele frühere Minor-Releases bringt PHP 8.4 eine ungewöhnlich hohe Zahl an Sprachfeatures. Property Hooks und Asymmetric Visibility verändern grundlegend, wie Klassen künftig geschrieben werden. Neue Array-Funktionen schließen Lücken, die Entwickler jahrelang mit array_filter- und array_values-Kombinationen umgehen mussten. Das neue #[\Deprecated]-Attribut bringt Deprecation-Handling erstmals direkt in die Sprache statt nur in Docblocks. In Summe zeigt das: die PHP 8.4 Features sind kein reines Wartungspaket, sondern verändern den täglichen Code von PHP-Entwicklern spürbar, und genau deshalb lohnt sich ein strukturierter Überblick, bevor man einzelne Themen vertieft.
Für Teams mit produktivem Code zählt neben neuen Möglichkeiten auch die Kompatibilität. PHP 8.4 macht einige stille Altlasten aus PHP-5- und PHP-7-Zeiten sichtbar, etwa implizite nullable-Parameter oder veraltete DOM-Nutzung, und verwandelt sie in explizite Deprecation-Warnungen. Wer plant, in den nächsten Jahren auf PHP 8.4 zu wechseln, sollte deshalb nicht nur die neuen PHP 8.4 Features im Blick haben, sondern auch wissen, welche Codepfade beim Upgrade zuerst auffallen werden.
2. Property Hooks im Überblick
Property Hooks zählen zu den meistdiskutierten neuen PHP 8.4 Features: Sie erlauben es, get- und set-Logik direkt an einer Property zu deklarieren, ohne dass klassische getFoo()/setFoo()-Methodenpaare oder magische __get()/__set()-Implementierungen nötig sind. Eine Property kann dadurch berechnet werden, Eingaben validieren oder transparent auf eine andere Property zurückgreifen, während der Zugriff von außen weiterhin wie eine einfache Eigenschaft aussieht.
Weil Property Hooks ein eigenes Kapitel für sich sind, mit virtuellen Properties, Backing-Fields und dem Zusammenspiel mit Interfaces, geht dieser Überblicksartikel bewusst nicht in die Syntax-Details. Ein eigener vertiefender Artikel auf diesem Blog behandelt Property Hooks inklusive Backing-Fields und Vererbung im Detail. Für diesen Überblick reicht die Einordnung: Property Hooks gehören zu den wichtigsten neuen PHP 8.4 Features und reduzieren Boilerplate-Code in Entities und DTOs spürbar.
3. Asymmetric Visibility im Überblick
Asymmetric Visibility ergänzt Property Hooks um eine kleinere, aber ebenso einflussreiche Neuerung: Eine Property kann jetzt für Lesezugriffe eine andere Sichtbarkeit haben als für Schreibzugriffe, etwa public für lesenden Zugriff von außen, aber private(set) für schreibenden Zugriff nur innerhalb der eigenen Klasse. Damit entfällt ein sehr häufiges Boilerplate-Muster: eine private Property plus eine öffentliche Getter-Methode, nur um kontrollierten Lesezugriff bei internem Schreibzugriff zu ermöglichen.
Auch Asymmetric Visibility wird hier bewusst nur eingeordnet, nicht ausgeschöpft. Die Kombination mit readonly, mit Konstruktor-Promotion und mit Vererbung ist Thema eines eigenen vertiefenden Artikels auf diesem Blog. Für diesen Überblick über die PHP 8.4 Features reicht die Feststellung: Asymmetric Visibility macht Domain-Modelle und Value Objects lesbarer, ohne zusätzliche Getter-Methoden zu erzwingen.
4. Neue Array-Funktionen: array_find, array_any, array_all, array_find_key
Unter den neuen PHP 8.4 Features sind die vier neuen Array-Funktionen array_find(), array_any(), array_all() und array_find_key() vermutlich die, die im Alltag am häufigsten benutzt werden. Sie lösen ein Problem, das PHP-Entwickler jahrelang mit Workarounds umschifft haben: das Suchen nach dem ersten passenden Element einer Bedingung, ohne dafür array_filter() mit anschließendem array_values() und Index-Zugriff zu kombinieren. array_find() gibt den ersten Wert zurück, für den der Callback true liefert, oder null, wenn kein Element passt.
array_any() und array_all() prüfen, ob mindestens ein beziehungsweise alle Elemente eine Bedingung erfüllen, und brechen die Iteration ab, sobald das Ergebnis feststeht: array_any() stoppt beim ersten Treffer, array_all() beim ersten Nicht-Treffer. array_find_key() liefert analog zu array_find() nicht den Wert, sondern den Schlüssel des ersten passenden Elements zurück, was bei assoziativen Arrays mit sprechenden Schlüsseln besonders nützlich ist. Alle vier Funktionen erwarten einen Callback mit der Signatur function(mixed $value, int|string $key): bool, der Key-Parameter ist optional.
Der Vorteil gegenüber dem alten array_filter()+array_values()-Muster ist nicht nur Lesbarkeit, sondern auch Performance: array_filter() durchläuft immer das komplette Array und baut ein neues Zwischenarray auf, während array_find() und array_any() beim ersten Treffer abbrechen. Bei großen Collections, etwa Produktlisten in einem Magento-Katalog-Import oder Order-Historien, macht sich das durch weniger Speicherverbrauch und weniger CPU-Zeit bemerkbar.
declare(strict_types=1);
final class OrderService
{
/**
* @param array<int, Order> $orders
*/
public function __construct(private readonly array $orders) {}
public function firstOverdue(): ?Order
{
// Old approach before PHP 8.4: array_filter + array_values + index access
// $overdue = array_values(array_filter($this->orders, fn (Order $o) => $o->isOverdue()));
// return $overdue[0] ?? null;
// PHP 8.4: array_find stops at the first match, no intermediate array
return array_find(
$this->orders,
fn (Order $order): bool => $order->isOverdue()
);
}
public function hasOverdueOrder(): bool
{
return array_any($this->orders, fn (Order $o) => $o->isOverdue());
}
public function allOrdersPaid(): bool
{
return array_all($this->orders, fn (Order $o) => $o->isPaid());
}
public function firstOverdueOrderId(): int|string|null
{
return array_find_key($this->orders, fn (Order $o) => $o->isOverdue());
}
}
5. Das #[\Deprecated]-Attribut für eigene APIs
Mit dem Attribut #[\Deprecated] bekommt PHP erstmals eine sprachnative Möglichkeit, veraltete Funktionen, Methoden, Klassenkonstanten und Enum-Cases zu markieren, statt sich ausschließlich auf den @deprecated-Docblock-Tag zu verlassen. Die Syntax erlaubt zwei optionale benannte Parameter: message für eine menschenlesbare Erklärung, was stattdessen zu verwenden ist, und since für die Versionsnummer, ab der die Markierung gilt. Wird eine so markierte Funktion oder Methode aufgerufen, erzeugt PHP zur Laufzeit eine E_DEPRECATED-Warnung am Aufrufort, nicht an der Definitionsstelle.
Der praktische Unterschied zu einem reinen Docblock-Kommentar ist die Werkzeugunterstützung: IDEs wie PhpStorm und statische Analyzer wie PHPStan oder Psalm können das Attribut zuverlässig auswerten, ohne Docblock-Text parsen zu müssen, und markieren betroffene Aufrufe direkt im Editor durchgestrichen. Das reduziert das Risiko, dass eine als veraltet markierte Methode versehentlich weiterverwendet wird, weil der Hinweis im Docblock übersehen wurde.
Für die Migration bestehender Codebasen gilt: bestehende @deprecated-Docblocks müssen nicht sofort entfernt werden, beide Mechanismen können parallel existieren. Sinnvoll ist es, bei neuem Code direkt auf das native Attribut zu setzen und bestehende Docblock-Markierungen schrittweise zu ergänzen, weil nur das Attribut zur Laufzeit eine tatsächliche Warnung erzeugt und von Tooling maschinell auswertbar ist. Für Bibliotheks- und API-Entwickler ist das eines der praktisch nützlichsten neuen PHP 8.4 Features, weil es Deprecation-Zyklen deutlich verlässlicher macht.
declare(strict_types=1);
final class PriceCalculator
{
#[\Deprecated(
message: 'use calculateNet() instead, calculate() will be removed in a future major version',
since: '8.4'
)]
public function calculate(float $gross, float $taxRate): float
{
return $this->calculateNet($gross, $taxRate);
}
public function calculateNet(float $gross, float $taxRate): float
{
return $gross / (1 + $taxRate);
}
}
$calculator = new PriceCalculator();
$calculator->calculate(119.0, 0.19); // triggers E_DEPRECATED at the call site, not at the definition
6. Neue HTML5-konforme DOM-API
PHP 8.4 führt mit dem Namespace Dom\ eine komplett neue DOM-API ein: Dom\HTMLDocument für HTML-Dokumente und Dom\XMLDocument für XML. Beide Klassen parsen Dokumente nach den tatsächlichen WHATWG- beziehungsweise HTML5-Spezifikationen, statt sich wie die alte DOMDocument-Klasse auf das deutlich laxere und in Details inkonsistente HTML-Parsing von libxml2 zu verlassen. Fehlerhaftes oder unvollständiges HTML aus der Praxis, etwa nicht geschlossene Tags oder fehlerhafte Verschachtelung, wird dadurch berechenbarer verarbeitet.
Ein zweiter, sehr praxisrelevanter Unterschied: Die neuen Klassen bringen querySelector() und querySelectorAll() direkt mit. Damit lassen sich Elemente über echte CSS-Selektoren finden, ohne für einfache Abfragen umständliche XPath-Ausdrücke schreiben zu müssen, was DOMDocument bislang erzwang. Für Aufgaben wie das Extrahieren von Preisen oder Produktdaten aus HTML-Fragmenten, etwa beim Parsen von Lieferanten-Feeds, ist das ein spürbarer Produktivitätsgewinn.
Die alte DOMDocument-Klasse wird nicht entfernt und bleibt für Bestandscode nutzbar, aber für neuen Code empfiehlt sich der Wechsel auf die neue DOM-API, sobald PHP 8.4 als Mindestversion feststeht. Gerade in Content-lastigen Magento- oder CMS-Projekten, in denen HTML-Fragmente serverseitig nachbearbeitet werden, gehört die neue DOM-API zu den unterschätzten PHP 8.4 Features, weil sie sowohl Korrektheit als auch Lesbarkeit verbessert.
declare(strict_types=1);
use Dom\HTMLDocument;
$fragment = <<<'HTML'
<div class="product" data-sku="MS-1001">
<p class="title">Hyva Theme Paket</p>
<span class="price">129,00 EUR</span>
</div>
HTML;
// New in PHP 8.4: HTML5-compliant parsing, no libxml quirks-mode guessing
$document = HTMLDocument::createFromString($fragment, LIBXML_NOERROR);
// querySelector/querySelectorAll: real CSS selectors, no XPath required
$priceNode = $document->querySelector('.product .price');
echo $priceNode?->textContent; // 129,00 EUR
foreach ($document->querySelectorAll('.product') as $product) {
echo $product->getAttribute('data-sku') . PHP_EOL;
}
7. Objekt-Instanziierung mit direktem Methodenaufruf
Bis einschließlich PHP 8.3 musste ein frisch instanziiertes Objekt in Klammern gesetzt werden, um direkt eine Methode darauf aufzurufen: (new Foo())->bar(). Diese Klammern waren reine Syntaxpflicht und trugen keine semantische Bedeutung, wurden aber von praktisch jedem PHP-Entwickler irgendwann vergessen und produzierten dann einen Parse-Error. PHP 8.4 erlaubt jetzt new Foo()->bar() ohne die umschließenden Klammern, was diesen ständigen kleinen Stolperstein beseitigt.
Die neue Syntax funktioniert nicht nur für Methodenaufrufe, sondern gleichermaßen für Property-Zugriff, den Zugriff auf Klassenkonstanten über eine Instanz und Array-Zugriff auf das Ergebnis eines new-Ausdrucks. Sie funktioniert auch bei verketteten Aufrufen und mit Konstruktor-Argumenten, verändert dabei aber ausschließlich die Syntax, keine Semantik: new Foo()->bar() erzeugt exakt dasselbe Verhalten wie (new Foo())->bar(), nur ohne die Klammern.
Für bestehenden Code ändert sich nichts, die Klammer-Schreibweise bleibt weiterhin gültig und wird von den meisten Codebasen aus Kompatibilitätsgründen zu älteren PHP-Versionen ohnehin noch eine Weile beibehalten. Wer aber ausschließlich auf PHP 8.4 als Mindestversion zielt, kann diese Boilerplate-Klammern schrittweise entfernen. Unter den neuen PHP 8.4 Features ist das die kleinste, rein kosmetische Änderung, aber eine, die täglich in fast jeder Codebasis sichtbar wird.
declare(strict_types=1);
final class PriceFormatter
{
public function __construct(private readonly string $locale = 'de_DE') {}
public function format(float $amount): string
{
return number_format($amount, 2, ',', '.') . ' EUR';
}
}
// Before PHP 8.4: extra parentheses were mandatory
$formatted = (new PriceFormatter('de_DE'))->format(129.0);
// PHP 8.4: direct method call without wrapping parentheses
$formatted = new PriceFormatter('de_DE')->format(129.0);
// Also works with property access
$locale = new PriceFormatter()->locale;
8. Performance-Verbesserungen und JIT-Anpassungen
Neben den sichtbaren Sprachfeatures bringt PHP 8.4 auch strukturelle Verbesserungen unter der Haube. Die vielleicht wichtigste davon sind Lazy Objects: Über ReflectionClass::newLazyGhost() und newLazyProxy() können Objekte erzeugt werden, deren tatsächliche Initialisierung erst beim ersten Zugriff auf eine Property stattfindet. Das ist besonders für ORMs und Dependency-Injection-Container relevant, die Objekte oft vorab referenzieren, aber nicht sofort vollständig befüllen müssen, etwa bei Lazy-Loading von Entity-Relationen in Doctrine oder ähnlichen Mappern.
Der JIT-Compiler wurde in PHP 8.4 auf ein neues internes Backend umgestellt, das auf einer eigenen Intermediate-Representation (IR) statt auf dem bisherigen DynASM-basierten Ansatz aufbaut. Praktisch bedeutet das bessere Codequalität, verbesserte Unterstützung für ARM64-Architekturen und eine wartbarere Grundlage für künftige Optimierungen, aber keinen dramatischen Geschwindigkeitssprung für typische PHP-FPM-Webworkloads, bei denen der JIT ohnehin selten den größten Hebel darstellt. Rechenintensive Skripte mit vielen numerischen Operationen profitieren spürbarer als klassische Request-Response-Zyklen in Magento oder Symfony.
Zusätzlich wurden zahlreiche interne Datenstrukturen und der Zend Memory Manager weiter optimiert, was sich vor allem im Speicherverbrauch unter hoher Nebenläufigkeit zeigt, etwa auf PHP-FPM-Workern mit vielen parallelen Requests. In Kombination mit den neuen Array-Funktionen, die intern ohne zusätzliche Zwischenarrays auskommen, ergeben die PHP 8.4 Features insgesamt eine spürbare, wenn auch keine spektakuläre Verbesserung der Ressourceneffizienz gegenüber PHP 8.3.
9. Breaking Changes und Migrationshinweise
Die wichtigste Verhaltensänderung in PHP 8.4 betrifft implizite nullable-Parametertypen. Eine Signatur wie function foo(int $x = null) wurde in PHP-Versionen bis 8.3 stillschweigend als ?int $x = null interpretiert. PHP 8.4 markiert dieses implizite Verhalten als deprecated und erzeugt bei jeder betroffenen Funktionsdefinition eine E_DEPRECATED-Warnung. Der Fix ist einfach, aber in großen Codebasen mit hunderten betroffenen Signaturen aufwendig: der Nullable-Typ muss explizit als ?int oder int|null ausgeschrieben werden.
Daneben verschärft PHP 8.4 einige seit Jahren als veraltet markierte Verhaltensweisen aus älteren DOM- und String-Funktionen sowie einzelne INI-Direktiven, die schon in PHP 8.1 oder 8.2 Deprecation-Warnungen ausgelöst hatten. Wer diese Warnungen in der Vergangenheit ignoriert hat, weil das Skript trotzdem funktionierte, muss beim Sprung auf PHP 8.4 mit tatsächlichen Fatal Errors statt bloßer Warnungen rechnen.
Für die Migration empfiehlt sich ein zweistufiges Vorgehen: Zunächst die bestehende Codebasis unter PHP 8.3 mit aktivierter E_DEPRECATED-Fehlerausgabe laufen lassen und alle Meldungen systematisch abarbeiten, danach automatisierte Refactoring-Tools wie Rector mit dem PHP-8.4-Regelsatz über den Code laufen lassen, um implizite nullable-Typen und ähnliche Muster automatisiert zu korrigieren. Erst danach sollte composer.json auf "php": "^8.4" angehoben werden, damit die neuen PHP 8.4 Features in Staging getestet werden können, bevor produktive Server umgestellt werden.
declare(strict_types=1);
// PHP 8.3 and earlier: implicit nullable, allowed without warning
function applyDiscount(int $percentage = null): float
{
return $percentage === null ? 0.0 : $percentage / 100;
}
// PHP 8.4: implicit nullable triggers E_DEPRECATED
// "Implicitly marking parameter type as nullable is deprecated"
// Fixed version: explicit nullable type
function applyDiscountFixed(?int $percentage = null): float
{
return $percentage === null ? 0.0 : $percentage / 100;
}
Ein direkter Vergleich zeigt, wie sich einige der wichtigsten Muster von PHP 8.3 zu PHP 8.4 verändern und welchen konkreten Vorteil die neue Schreibweise jeweils bringt.
| Aufgabe | PHP 8.3 Ansatz | PHP 8.4 Ansatz | Vorteil |
|---|---|---|---|
| Erstes passendes Element finden | array_values(array_filter($a, $cb))[0] ?? null |
array_find($a, $cb) |
Kein Zwischenarray, Early Exit |
| Methode als veraltet markieren | /** @deprecated */ |
#[\Deprecated(message: '...')] |
Laufzeit-Warnung, IDE-Erkennung |
| HTML-Fragment parsen | DOMDocument::loadHTML() |
Dom\HTMLDocument::createFromString() |
HTML5-konform, querySelector |
| Methode direkt nach new aufrufen | (new Foo())->bar() |
new Foo()->bar() |
Kein Klammer-Boilerplate |
| Nullable-Parameter deklarieren | int $x = null (implizit) |
?int $x = null (explizit) |
Keine Deprecation-Warnung |
10. Zusammenfassung
PHP 8.4 Features im Überblick zeigen: Dieses Release ist deutlich mehr als ein jährliches Wartungsupdate. Property Hooks und Asymmetric Visibility verändern, wie Klassen geschrieben werden, auch wenn beide Themen hier bewusst nur angerissen und nicht ausgeschöpft wurden. Die vier neuen Array-Funktionen array_find(), array_any(), array_all() und array_find_key() lösen ein jahrelanges Boilerplate-Problem. Das #[\Deprecated]-Attribut, die neue DOM-API und die vereinfachte Objekt-Instanziierung runden das Bild ab.
Gleichzeitig bringt PHP 8.4 mit der Deprecation impliziter nullable-Typen eine Breaking Change, die praktisch jede ältere Codebasis betrifft und vor einem Upgrade systematisch geprüft werden sollte. Wer die neuen PHP 8.4 Features nutzen will, sollte deshalb nicht nur die Vorteile im Blick haben, sondern die Migration mit Tools wie Rector und einer sauberen Staging-Phase planen, statt produktiv blind zu aktualisieren.
PHP 8.4 Features, das Wichtigste auf einen Blick
Sieben Features im Fokus
Property Hooks, Asymmetric Visibility, Array-Funktionen, das #[\Deprecated]-Attribut, die neue DOM-API, die new-Syntax und Performance bilden den Kern der PHP 8.4 Features.
Array-Funktionen ohne Workarounds
array_find, array_any, array_all und array_find_key ersetzen array_filter+array_values-Kombinationen mit Early-Exit-Verhalten.
DOM-API HTML5-konform
Dom\HTMLDocument und Dom\XMLDocument bringen querySelector-Unterstützung und spezifikationskonformes Parsing mit.
Breaking Change: Nullable explizit machen
Implizite nullable-Parameter sind deprecated. ?int statt int = null schreiben, idealerweise automatisiert mit Rector migrieren.
11. FAQ: PHP 8.4 Features im Überblick
1Was sind die wichtigsten PHP 8.4 Features im Überblick?
2Muss ich Property Hooks in PHP 8.4 sofort verwenden?
3Was ist der Unterschied zwischen array_find und array_filter?
4Wie funktioniert das #[\Deprecated]-Attribut in PHP 8.4?
5Muss ich DOMDocument durch die neue DOM-API ersetzen?
6Was bedeutet new Foo()->bar() in PHP 8.4?
7Ist PHP 8.4 spürbar schneller als PHP 8.3?
8Was sind Lazy Objects in PHP 8.4?
9Was bricht beim Upgrade auf PHP 8.4 am häufigsten?
10Bis wann wird PHP 8.4 unterstützt?
Mironsoft
PHP 8.4 Migration, Code-Modernisierung und Legacy-Refactoring
Bereit für die neuen PHP 8.4 Features in eurem Projekt?
Wir prüfen bestehenden PHP-Code auf Breaking Changes, migrieren Magento- und Symfony-Projekte sauber auf PHP 8.4 und modernisieren Legacy-Klassen mit Property Hooks, Asymmetric Visibility und den neuen Array-Funktionen.
PHP 8.4 Migrations-Audit
Analyse aller impliziten nullable-Typen, veralteten DOM-Aufrufe und weiterer Breaking Changes vor dem Upgrade
Code-Modernisierung
Refactoring bestehender Klassen mit Property Hooks, Asymmetric Visibility und dem #[\Deprecated]-Attribut
Performance-Review
Bewertung von JIT-Konfiguration, Lazy Objects und Speicherverbrauch für Magento- und Symfony-Deployments