La RC1 de PHP 8.4 est tombée le 29 août 2024, marquant le feature-freeze officiel avant la GA prévue le 21 novembre. Les property hooks ont monopolisé l'attention — à juste titre — mais trois autres fonctionnalités méritent autant de vigilance si tu prépares une montée de version Symfony ou une bibliothèque maison : les lazy objects natifs, la nouvelle API Dom\HTMLDocument compatible HTML5, et les helpers array_find / array_any / array_all. Tour d'horizon technique avant novembre.
Lazy objects natifs : fini ocramius/proxy-manager
Jusqu'ici, instancier un service à la demande en PHP nécessitait soit une librairie externe (ocramius/proxy-manager, Symfony lazy proxy), soit du code artisanal. PHP 8.4 intègre ce mécanisme nativement via ReflectionClass. Deux modes coexistent : le lazy ghost (l'objet lui-même, initialisé au premier accès à une propriété) et le lazy proxy (un proxy qui délègue à une vraie instance créée à la demande). Le ghost couvre la majorité des scénarios d'injection de dépendances.
<?php
// PHP 8.4 — lazy ghost object
class HeavyAnalyticsService
{
public function __construct(
private readonly DatabaseConnection $db,
private readonly HttpClient $http,
) {}
public function fetchReport(int $projectId): array
{
return $this->db->query('SELECT * FROM reports WHERE project_id = ?', [$projectId]);
}
}
$reflector = new ReflectionClass(HeavyAnalyticsService::class);
// L'initialiseur ne s'exécute qu'au premier accès réel
$service = $reflector->newLazyGhost(function (HeavyAnalyticsService $instance): void {
$instance->__construct(
new DatabaseConnection($_ENV['DATABASE_URL']),
new HttpClient(['timeout' => 5]),
);
});
// Ici, aucune connexion ouverte.
// La connexion DB s'établit seulement à cette ligne :
$report = $service->fetchReport(42);Pour les containers DI, le bénéfice est immédiat : aucune dépendance PECL, aucun générateur de classes proxy au build. Symfony explore déjà ce mécanisme dans sa branche de développement pour remplacer son propre système de lazy proxy — un signal fort sur l'impact à venir en production.
Dom\HTMLDocument : enfin un parser HTML5 correct
DOMDocument était un wrapper autour d'une librairie XML datant des années 90. Il tolère le HTML au prix d'avertissements, massacre les entités HTML5 et ignore la sémantique réelle du navigateur. Dom\HTMLDocument (nouvelle API, namespace dédié) repose sur Lexbor, un parser HTML5 certifié. Le changement le plus visible au quotidien : querySelector et querySelectorAll sont enfin disponibles nativement en PHP, sans contorsion XPath.
<?php
// PHP 8.4 — nouvelle API Dom\HTMLDocument
$html = <<<'HTML'
<!DOCTYPE html>
<html lang="fr">
<body>
<nav>
<a href="/" class="nav-link active">Accueil</a>
<a href="/blog" class="nav-link">Blog</a>
</nav>
<main>
<article data-id="12">
<h1>Mon article</h1>
<p>Contenu <strong>important</strong>.</p>
</article>
</main>
</body>
</html>
HTML;
$doc = Dom\HTMLDocument::createFromString($html, LIBXML_NOERROR);
// querySelector natif, sans bricolage XPath
$nav = $doc->querySelector('nav');
$links = $nav->querySelectorAll('a.nav-link');
foreach ($links as $link) {
echo $link->textContent . ' → ' . $link->getAttribute('href') . PHP_EOL;
}
// Récupération d'un attribut data-* sur l'article
$article = $doc->querySelector('article[data-id]');
echo 'Article ID : ' . $article->getAttribute('data-id'); // 12L'ancienne classe DOMDocument reste disponible pour la rétrocompatibilité, mais pour tout nouveau code de scraping, de génération ou d'analyse HTML, Dom\HTMLDocument est la cible à privilégier. Les entités HTML comme ou é sont correctement gérées sans warnings — ce qui évite des centaines de libxml_use_internal_errors(true) éparpillés dans les bases de code existantes.
Migration Symfony en vue ?
Estimer ma migration →array_find, array_any, array_all : l'outillage qui manquait
Retrouver le premier élément d'un tableau satisfaisant une condition exigeait jusqu'ici de combiner array_filter et reset(), ou d'écrire une boucle manuelle. PHP 8.4 normalise ce pattern avec quatre helpers issus d'un RFC direct et lisible.
<?php
// PHP 8.4 — array_find / array_find_key / array_any / array_all
$users = [
['id' => 1, 'role' => 'user', 'active' => true],
['id' => 2, 'role' => 'admin', 'active' => true],
['id' => 3, 'role' => 'admin', 'active' => false],
];
// Premier élément correspondant au critère
$firstAdmin = array_find($users, fn($u) => $u['role'] === 'admin');
// → ['id' => 2, 'role' => 'admin', 'active' => true]
// Clé du premier élément correspondant
$key = array_find_key($users, fn($u) => $u['id'] === 3);
// → 2
// Au moins un admin actif ?
$hasActiveAdmin = array_any($users, fn($u) => $u['role'] === 'admin' && $u['active']);
// → true
// Tous les users actifs ?
$allActive = array_all($users, fn($u) => $u['active']);
// → false (user 3 inactif)array_find(array, callable): mixed|null— retourne la première valeur satisfaisant le callback, ou nullarray_find_key(array, callable): int|string|null— retourne la clé du premier élément satisfaisant le callbackarray_any(array, callable): bool— true si au moins un élément satisfait le callbackarray_all(array, callable): bool— true si tous les éléments satisfont le callback
Ces quatre fonctions acceptent un callable classique, une closure ou une arrow function. Elles ne modifient pas le tableau source et court-circuitent dès la première correspondance trouvée — contrairement à array_filter qui itère la totalité du tableau. Le gain principal est en lisibilité et en intention explicite dans les couches métier.
Ce que ça change pour tes projets dès novembre
PHP 8.4 GA le 21 novembre 2024 n'est pas une version cosmétique. Les lazy objects natifs réduisent la surface de dépendance des containers DI et des ORMs. Dom\HTMLDocument rend le parsing HTML de qualité production sans librairie tierce. Les helpers array_find et consorts nettoient des patterns récurrents dans tout code métier. La migration depuis PHP 8.3 sera légère côté breaking changes — c'est le bon moment pour planifier la montée de version. Si tu veux un état des lieux de ta base de code avant de sauter le pas, un Bear Scan identifie les incompatibilités, les extensions à mettre à jour et les patterns qui bénéficieront le plus des nouvelles APIs.
Migration Symfony en vue ?
Bear Upgrade migre votre codebase 3-5× moins cher qu'une ESN.