Ce qui change concrètement depuis PHP 8.2
PHP 8.2 a marqué un tournant vers plus de rigueur dans le typage et l'immutabilité, et les versions 8.3/8.4 ont continué dans cette direction. Voici les points qui méritent une vraie relecture si vous n'avez pas suivi de près.
Classes readonly entières
Avant 8.2, il fallait marquer chaque propriété readonly individuellement. Désormais, on peut appliquer le modificateur sur la classe entière :
readonly class Point
{
public function __construct(
public float $x,
public float $y,
) {}
}
Toutes les propriétés typées deviennent implicitement readonly. Attention : une classe readonly ne peut pas être étendue par une classe qui ne l'est pas, et on ne peut plus faire de "clone + modif" classique — il faut recréer l'objet ou passer par clone with (arrivé en 8.5 dans les discussions RFC, mais absent en 8.2/8.3).
Types DNF (Disjunctive Normal Form)
PHP 8.2 introduit la combinaison d'intersection et d'union de types :
function process((Countable&Iterator)|null $data): void {}
Cela permet d'exprimer "un objet qui implémente à la fois Countable et Iterator, ou null" sans passer par une interface intermédiaire artificielle.
Fin des propriétés dynamiques
C'est le changement le plus disruptif : instancier une propriété non déclarée sur un objet standard déclenche désormais un deprecation warning (et deviendra une erreur fatale à terme).
class User {}
$u = new User();
$u->name = 'Alex'; // Deprecated: Creation of dynamic property
Pour autoriser ce comportement volontairement, ajoutez l'attribut #[AllowDynamicProperties] sur la classe. Les classes héritant de stdClass restent exemptées.
Constantes typées et enums en interface (8.3)
PHP 8.3 permet de typer les constantes de classe, ce qui sécurise les contrats d'interface :
interface HasLimit
{
const int MAX = 100;
}
Les enums peuvent aussi implémenter des interfaces contenant des constantes, ce qui les rend plus proches de véritables value objects.
json_validate() et une meilleure gestion mémoire (8.3)
Plutôt que de faire json_decode() puis vérifier json_last_error() juste pour valider une syntaxe, json_validate($json) retourne un booléen sans construire la structure PHP intermédiaire — un gain net en performance pour les validations de payloads volumineux.
À retenir pour la migration
- Activez
error_reportingavec les deprecations en environnement de test avant de passer en 8.2+, pour repérer les propriétés dynamiques implicites. - Les types DNF ne sont utiles qu'avec des interfaces déjà bien découpées : si vos interfaces sont trop larges, l'intersection perd son intérêt.
- Les classes
readonlyforcent à repenser les patterns de mutation en "with-er" (méthodes qui retournent une nouvelle instance modifiée).