Comment utiliser les propriétés en lecture seule dans PHP 8.1

0
165

PHP 8.1 ajoute la prise en charge d'un modificateur en lecture seule sur les propriétés de classe. Une propriété balisée de cette manière ne peut être définie qu'une seule fois. Essayer de modifier la valeur d'une propriété en lecture seule après l'initialisation générera une erreur.

“Lecture seule” est un terme assez vague, avec des implications variables dans les langages de programmation individuels. Dans ce contexte, “lecture seule” signifie vraiment “immuable”—vous pouvez définir la valeur d'une propriété, mais elle ne peut plus être modifiée par la suite.

Écriture de propriétés en lecture seule

Ajoutez le modificateur readonly pour rendre une propriété en lecture seule. Il doit être placé entre le modificateur d'accès de la propriété et son indice de type.

class Demo {   chaîne publique $Mutable ;   chaîne publique en lecture seule $Immutable ;   fonction publique __construct( chaîne $Mutable, chaîne $Immuable) {   $ceci -> Mutable = $Mutable ; $ceci -> Immuable = $Immuable ; }   }

$Mutable est une propriété publique normale. Vous pouvez modifier sa valeur à tout moment, que ce soit dans les méthodes de classe ou de l'extérieur :

$demo = nouvelle démo("A", "X"); $démo -> Mutable = "B";

$Immuable est un peu différent. Vous pouvez toujours lire sa valeur quand vous le souhaitez, mais toute modification échouera avec une erreur :

//Génère une erreur $demo -> Immuable = "O"; Publicité

Le modificateur readonly est également pris en charge dans les propriétés de constructeur promues :

class Demo { fonction publique __construct( chaîne publique en lecture seule $Immutable="foobar" ) {} }

Vous pouvez toujours définir la propriété manuellement dans votre constructeur lorsque vous utilisez la promotion avec une valeur par défaut. C'est le paramètre de fonction qui reçoit la valeur par défaut, pas l'instance de propriété. La promotion se desucres au même code montré dans l'exemple précédent.

Mises en garde

Les propriétés en lecture seule sont une amélioration de la syntaxe simple que vous pouvez adopter à votre guise. Il n'y a pas d'implications de compatibilité descendante et leur utilisation est entièrement facultative. Si vous commencez à les ajouter, il y a quelques mises en garde et limitations à prendre en compte.

Contrairement aux propriétés ordinaires, les propriétés en lecture seule ne sont pas autorisées à avoir une valeur par défaut dans leur définition :

classe Démo { chaîne protégée en lecture seule $foo = "bar"; }

Cette instruction définit et initialise $foo. Vous ne pouvez pas modifier sa valeur après l'initialisation, la propriété est donc en fait une constante. Par conséquent, les valeurs par défaut sont interdites et vous devez utiliser une vraie constante à la place :

classe Démo { const foo = "barre"; }

Suite à cette restriction, la lecture seule n'est prise en charge que sur les propriétés typées. La propriété suivante a une définition illégale :

class Demo { protégé en lecture seule $foo ; } Publicité

Une propriété non typée, comme $foo ci-dessus, a une valeur par défaut implicite de null. Si la lecture seule était autorisée, l'option “pas de constantes implicites” la règle refait surface. Les propriétés typées font la distinction entre “non initialisé” et “nulle” états, ils existent donc sans aucune valeur jusqu'à ce que vous en définissiez une explicitement.

Le modificateur readonly a des règles spéciales lorsqu'il est utilisé dans le cadre de l'héritage de classe. Les classes enfants ne peuvent pas ajouter ou supprimer en lecture seule sur les propriétés définies par leurs parents.

Rendre une propriété accessible en écriture en lecture seule casserait la classe parente si ses méthodes modifiaient la valeur. Bien que la suppression de la contrainte soit apparemment inoffensive, la RFC considère en lecture seule une “restriction intentionnelle” des capacités qui seraient perdues si les remplacements d'héritage étaient autorisés. Il est interdit aux classes parents d'affirmer que les enfants ne peuvent pas provoquer d'effets secondaires en modifiant les propriétés qui sont censées être en lecture seule.

Les propriétés en lecture seule ne peuvent être définies que dans la portée dans laquelle ils sont définis. Cela signifie que les propriétés publiques ne peuvent pas être définies depuis l'extérieur d'une classe, même si elles n'ont pas été initialisées auparavant :

classe Démo { chaîne publique en lecture seule $foo ; }   $d = nouvelle démo(); $d -> foo = "barre"; //illégal

L'initialisation doit se produire dans la classe qui définit la propriété. En conséquence, les propriétés en lecture seule sont plus proches des champs immuables d'autres langages de programmation par opposition aux propriétés PHP préexistantes.

Le modificateur readonly s'applique également à toutes les écritures. Il ne fait pas la distinction entre l'accès interne et externe. Vous ne pouvez pas avoir une propriété qui est en lecture seule publiquement mais accessible en écriture dans la classe, bien qu'une future extension de spécification puisse le permettre.

Publicité

Un dernier problème concerne le mot-clé clone. Ce code ne fonctionnera pas :

classe Demo { fonction publique __construct( chaîne publique $foo ) {} }   $d = nouvelle démo("bar"); $d2 = cloner $d ; $d2 -> foo = "foobar";

Le clonage suit les mêmes règles que les accès aux propriétés classiques. Même si la modification de foobar est la première fois que foo est accédé sur $d2, la propriété a déjà été initialisée par le processus de clonage. Il y a une initialisation implicite lors du clonage.

Quand utiliser les propriétés en lecture seule ?

Les propriétés en lecture seule accéléreront considérablement la création de classes simples, qui représentent des structures de données. Il est courant d'écrire des classes jetables pour contenir les paramètres de requête HTTP, les objets de transfert de données et les données de réponse. Celles-ci sont généralement immuables, où les propriétés ne sont pas censées changer après la construction de la classe.

Vous aviez auparavant deux choix peu attrayants lors de l'écriture de classes de type struct : utiliser des propriétés publiques, accélérer le développement mais autoriser modification ou passer du temps à ajouter manuellement des méthodes getter pour exposer les propriétés protégées.

//Pas idéal – Les propriétés peuvent être modifiées en externe class UserCreationRequest { fonction publique __construct( chaîne publique $Nom d'utilisateur, chaîne publique $Mot de passe ) {} }   //Pas idéal non plus – Beaucoup de classe de code passe-partout UserCreationRequest { fonction publique __construct( chaîne protégée $Nom d'utilisateur, chaîne protégée $Mot de passe ) {}   fonction publique getUsername() : chaîne { renvoie $this -> Nom d'utilisateur; }   fonction publique getPassword() : chaîne { renvoie $this -> Mot de passe; } }

Les propriétés en lecture seule permettent enfin l'approche idéale :

classe UserCreationRequest { fonction publique __construct( chaîne publique en lecture seule $Username, chaîne publique en lecture seule $Password ) {} }

Les propriétés sont accessibles au public mais immuables. Combinées à la promotion des propriétés du constructeur, les propriétés en lecture seule promettent de réduire considérablement le code passe-partout, vous permettant d'écrire des classes utiles plus rapidement.

readonly facilite également la lisibilité du code et indique mieux vos intentions. Quiconque lit ou modifie la classe UserCreationRequest sait que ses propriétés ne sont pas censées changer. Dans le premier exemple, on ne sait pas si un autre code du projet modifie directement les propriétés de la classe. Le deuxième exemple est un peu plus clair, mais pourrait tout de même inciter un développeur à implémenter des méthodes redondantes setUsername() et setPassword().

Conclusion

Le modificateur readonly apporte support d'immuabilité intégré aux propriétés de classe PHP. Cela rend votre code plus clair et empêche les changements de valeur involontaires en appliquant l'immuabilité au moment de l'exécution.

Publicité

En revenant à la série de versions de PHP 7, créant une classe de base de type struct utilisée pour impliquer la définition de propriétés typées, écrire un constructeur qui définit ces propriétés, puis ajouter des méthodes getter pour exposer leurs valeurs. Avec PHP 8.1, vous pouvez condenser tout cela en une seule signature de constructeur en combinant lecture seule publique et promotion de propriété.

Les propriétés en lecture seule sont implémentées dans les dernières versions de développement de PHP 8.1. La version prête pour la production arrivera en novembre 2021.