Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

Propriétés en lecture seule de PHP 8.2 : ce qu’elles apportent à une extension

PHP 8.2 introduit les propriétés readonly. Voici où elles apportent une vraie garantie d'architecture dans une extension WordPress, et où elles ne servent à rien.

Par WordPress Développement • 2 décembre 2023 • 5 min de lecture • Aucun commentaire
Propriétés en lecture seule de PHP 8.2 : ce qu'elles apportent à une extension

Le 8 décembre 2022, PHP 8.2 introduit les propriétés en lecture seule, déclarées avec le mot-clé readonly devant une propriété typée. Pour un développeur qui modernise l’architecture d’une extension WordPress, la question naturelle est de savoir si cette fonctionnalité apporte une réelle garantie de sécurité, ou si elle n’est qu’une contrainte syntaxique supplémentaire sans effet concret sur la robustesse du code.

La réponse tient en une nuance importante : une propriété readonly ne protège pas contre une mauvaise valeur, elle protège contre une modification après construction. Comprendre cette distinction évite de lui prêter des vertus qu’elle n’a pas.

Définition et règle d’écriture unique

Une propriété déclarée readonly ne peut recevoir une valeur qu’une seule fois, et uniquement depuis le scope de la classe qui la déclare, typiquement dans le constructeur :

final class LigneCommande {
    public readonly string $reference;
    public readonly int $quantite;

    public function __construct( string $reference, int $quantite ) {
        $this->reference = $reference;
        $this->quantite  = $quantite;
    }
}

Toute tentative d’écriture ultérieure, y compris depuis l’intérieur de la classe elle-même après la première initialisation, déclenche une erreur fatale Error: Cannot modify readonly property LigneCommande::$quantite. Cette contrainte s’applique aussi bien à une écriture externe qu’à une seconde écriture interne, ce qui la distingue d’un simple modificateur de visibilité private.

Fonctionnement interne : ce qui se passe réellement

L'essentiel à retenir : Une propriété readonly ne peut être écrite qu'une fois, depuis son propre scope ; Elle ne remplace pas la validation, seulement l'immutabilité après construction ; Incompatible avec les tableaux modifiables en place

PHP marque en interne chaque propriété readonly comme initialisée dès sa première affectation, dans une table de suivi propre à l’instance de l’objet. Une propriété readonly doit obligatoirement être typée : readonly $valeur sans type est une erreur de syntaxe. Elle ne peut pas non plus avoir de valeur par défaut dans sa déclaration, puisque toute valeur par défaut constituerait déjà une première écriture hors du constructeur.

Un point souvent mal compris concerne les objets et tableaux référencés par une propriété readonly : la propriété elle-même ne peut pas être réassignée, mais si elle référence un objet mutable, les propriétés internes de cet objet restent modifiables, sauf si elles sont elles-mêmes déclarées readonly dans leur propre classe.

Cas d’usage dans une extension : les value objects

Le terrain le plus naturel pour readonly dans une extension WordPress est la construction de petits objets de valeur, représentant une donnée métier figée une fois créée : une adresse, un montant, une référence de commande. Là où une extension classique aurait manipulé un tableau associatif array( 'reference' => ..., 'quantite' => ... ), modifiable à tout moment par n’importe quelle fonction qui le reçoit, un objet readonly garantit que la donnée reste identique du début à la fin de son cycle de vie dans le code :

function calculer_total( LigneCommande $ligne, float $prix_unitaire ): float {
    // $ligne->quantite est garanti inchangé depuis sa création,
    // quel que soit le nombre de fonctions qui l'ont manipulé avant.
    return $ligne->quantite * $prix_unitaire;
}

Ce n’est pas qu’une question de style : dans une extension où plusieurs filtres WordPress peuvent successivement modifier une structure de données avant qu’elle n’atteigne son traitement final, un tableau associatif classique laisse la porte ouverte à des modifications indésirables et difficiles à tracer. Un objet readonly, lui, produit une erreur fatale immédiate et explicite dès qu’une tentative de modification survient, ce qui transforme un bug silencieux en erreur détectable au moment du développement.

Pièges à éviter

  • Déclarer une propriété readonly sans type provoque une erreur de syntaxe : le typage est obligatoire, pas optionnel.
  • Une classe qui hérite d’une classe avec une propriété readonly ne peut pas redéclarer cette propriété comme non-readonly dans l’enfant : la contrainte se propage.
  • Cloner un objet contenant des propriétés readonly via clone conserve leurs valeurs sans permettre de les modifier ensuite dans __clone(), sauf en PHP 8.3 qui assouplit ce point précis avec la possibilité de réinitialiser une propriété readonly depuis __clone().
  • Confondre readonly avec une validation de valeur : rien n’empêche d’assigner une valeur incohérente au constructeur, la protection ne porte que sur l’immutabilité après coup, pas sur la pertinence de la donnée initiale.

Ce que readonly ne remplace pas

Les propriétés readonly ne dispensent pas de valider les données en entrée du constructeur. Une classe sérieuse continue de lever une exception si une valeur reçue est invalide, avant même de l’assigner à une propriété readonly :

public function __construct( string $reference, int $quantite ) {
    if ( $quantite < 1 ) {
        throw new InvalidArgumentException( 'La quantité doit être positive.' );
    }

    $this->reference = $reference;
    $this->quantite  = $quantite;
}

Notre verdict

Sur nos extensions migrées vers PHP 8.2, l’introduction de value objects readonly à la place de tableaux associatifs a supprimé une catégorie entière de bugs liés à une modification accidentelle de données en cours de traitement, sans coût de performance mesurable. Cette fonctionnalité mérite d’être adoptée dès qu’une extension impose un minimum de version PHP à 8.2, en particulier sur les structures de données qui traversent plusieurs filtres avant leur usage final.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi