SmartObject
SmartObject a amélioré pendant des années le comportement des objets en PHP. Depuis PHP 8.4, toutes ses fonctionnalités font partie intégrante de PHP, accomplissant ainsi sa mission historique de pionnier de l'approche orientée objet moderne en PHP.
Installation :
SmartObject est né en 2007 comme une solution révolutionnaire aux limitations du modèle objet de PHP de l'époque. À une période où PHP souffrait de nombreux problèmes de conception orientée objet, il a apporté des améliorations significatives et simplifié le travail des développeurs. Il est devenu une partie légendaire du framework Nette. Il proposait des fonctionnalités que PHP n'obtiendrait que de nombreuses années plus tard – de la validation d'accès aux propriétés jusqu'à la gestion sophistiquée des erreurs. Avec l'arrivée de PHP 8.4, il a achevé sa mission historique, car toutes ses fonctionnalités sont devenues des parties natives du langage. Il était en avance sur le développement de PHP de 17 années remarquables.
SmartObject a connu une évolution technique intéressante. Initialement, il était implémenté comme une classe
Nette\Object
, dont les autres classes héritaient les fonctionnalités nécessaires. Un changement majeur est survenu
avec PHP 5.4, qui a introduit le support des traits. Cela a permis sa transformation en trait Nette\SmartObject
,
apportant plus de flexibilité – les développeurs pouvaient utiliser ses fonctionnalités même dans les classes qui
héritaient déjà d'une autre classe. Alors que la classe originale Nette\Object
a cessé d'exister avec PHP 7.2
(qui interdisait de nommer les classes avec le mot ‚Object‘), le trait Nette\SmartObject
continue d'exister.
Examinons les fonctionnalités que Nette\Object
et plus tard Nette\SmartObject
offraient. Chacune de
ces fonctions représentait à l'époque une avancée significative dans la programmation orientée objet en PHP.
États d'erreur cohérents
L'un des problèmes les plus pressants du PHP initial était le comportement incohérent lors du travail avec les objets.
Nette\Object
a apporté ordre et prévisibilité dans ce chaos. Voici comment PHP se comportait à l'origine :
Une erreur fatale arrêtait l'application sans possibilité de réaction. L'écriture silencieuse dans des membres non
existants sans avertissement pouvait conduire à des erreurs graves difficiles à détecter. Nette\Object
capturait
tous ces cas et lançait une exception MemberAccessException
, permettant aux programmeurs de réagir et de gérer ces
erreurs :
Depuis PHP 7.0, le langage ne provoque plus d'erreurs fatales non capturables, et depuis PHP 8.2, l'accès aux membres non déclarés est considéré comme une erreur.
Assistant « Did you mean ? »
Nette\Object
est venu avec une fonctionnalité très pratique : des suggestions intelligentes pour les fautes de
frappe. Quand un développeur faisait une erreur dans le nom d'une méthode ou d'une variable, il ne signalait pas seulement
l'erreur mais proposait aussi une aide en suggérant le nom correct. Ce message iconique, connu sous le nom de « did you mean ?
», a fait gagner aux programmeurs des heures de recherche de fautes de frappe :
Bien que PHP lui-même n'ait aucune forme de « did you mean ? », cette fonctionnalité est maintenant fournie par Tracy. Il peut même auto-corriger ces erreurs.
Propriétés avec accès contrôlé
Une innovation significative que SmartObject a apportée à PHP était les propriétés avec accès contrôlé. Ce concept, courant dans des langages comme C# ou Python, permettait aux développeurs de contrôler élégamment l'accès aux données d'objet et d'assurer leur cohérence. Les propriétés sont un outil puissant de la programmation orientée objet. Elles fonctionnent comme des variables mais sont en réalité représentées par des méthodes (getters et setters). Cela permet la validation des entrées ou la génération de valeurs au moment de la lecture.
Pour utiliser les propriétés, vous devez :
- Ajouter l'annotation
@property <type> $xyz
à la classe - Créer un getter nommé
getXyz()
ouisXyz()
, un setter nommésetXyz()
- Vous assurer que le getter et le setter sont public ou protected. Ils sont optionnels – peuvent donc exister comme propriétés read-only ou write-only
Voyons un exemple pratique avec la classe Circle, où nous utiliserons les propriétés pour garantir que le rayon est toujours
non négatif. Nous remplacerons public $radius
par une propriété :
Depuis PHP 8.4, la même fonctionnalité peut être réalisée en utilisant les property hooks, qui offrent une syntaxe beaucoup plus élégante et concise :
Extension Methods
Nette\Object
a apporté un autre concept intéressant à PHP inspiré des langages de programmation modernes –
les extension methods. Cette fonctionnalité, empruntée à C#, permettait aux développeurs d'étendre élégamment les classes
existantes avec de nouvelles méthodes sans les modifier ni en hériter. Par exemple, vous pouviez ajouter une méthode
addDateTime()
à un formulaire qui ajoute un DateTimePicker personnalisé :
Les extension methods se sont révélées peu pratiques car les éditeurs ne suggéraient pas leurs noms et signalaient au contraire que la méthode n'existait pas. Par conséquent, leur support a été abandonné. Aujourd'hui, il est plus courant d'utiliser la composition ou l'héritage pour étendre les fonctionnalités des classes.
Obtention du nom de la classe
SmartObject proposait une méthode simple pour obtenir le nom de la classe :
Accès à la réflexion et aux annotations
Nette\Object
fournissait un accès à la réflexion et aux annotations via les méthodes
getReflection()
et getAnnotation()
. Cette approche simplifiait significativement le travail avec les
méta-informations des classes :
Depuis PHP 8.0, il est possible d'accéder aux méta-informations via les attributs, qui offrent encore plus de possibilités et un meilleur contrôle de type :
Getters de méthodes
Nette\Object
offrait une façon élégante de passer des méthodes comme s'il s'agissait de variables :
Depuis PHP 8.1, vous pouvez utiliser la first-class callable syntax, qui pousse ce concept encore plus loin :
Événements
SmartObject offre une syntaxe simplifiée pour travailler avec les événements. Les événements permettent aux objets d'informer les autres parties de l'application des changements de leur état :
Le code $this->onChange($this, $radius)
est équivalent à la boucle suivante :
Pour plus de clarté, nous recommandons d'éviter la méthode magique $this->onChange()
. Un remplacement
pratique est la fonction Nette\Utils\Arrays::invoke :