Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Verification de la nature d'un objet

5 réponses
Avatar
Luc
Bonjour,

J'aimerais savoir si c'est courant de vérifier la nature d'un objet en
php.

Supposons que j'ai une classe Voiture ayant un membre privé _moteur.

Lors de la création d'une voiture, on doit lui passer un objet Moteur
en paramètre.

Étant donné que php n'est pas typé, on peut passer n'importe quoi au
constructeur: un entier, un tableau ou un autre type d'objet...

Dans la classe voiture si je fais $this->_moteur->arreter() et que
_moteur est un entier, on devine la catastrophe.

Donc, dans le constructeur, je me dis que je devrais vérifier si je
reçois bien un moteur avec instanceOf.

Cependant, je trouve que ça alourdit le code et me dis que c'est au
"propriétaire" de la voiture de lui fournir un moteur valide.

Merci de vos conseils et opinions.

Au plaisir.

Luc

5 réponses

Avatar
Alarch
Luc wrote:


Cependant, je trouve que ça alourdit le code et me dis que c'est au
"propriétaire" de la voiture de lui fournir un moteur valide.



Il me semble être de bonne pratique de contrôler toute donnée fournie à un
script.

D'où vient la variable $moteur que tu dois fournir à ton objet ? Si il
existe un moyen quelconque pour l'internaute d'injecter autre chose qu'un
objet hadhoc dans ton moteur c'est ton script qui sera en panne !
Avatar
Mickaël Wolff
Luc a écrit :

J'aimerais savoir si c'est courant de vérifier la nature d'un objet en
php.



Ça dépend de la confiance qu'à le programmeur en les autres
programmeurs, et en soit-même.

Étant donné que php n'est pas typé, on peut passer n'importe quoi au
constructeur: un entier, un tableau ou un autre type d'objet...



Attention ! Il y a des gens qui disent que cette approche est
fortement typée :-D Enfin bref, depuis PHP5, on peut spécifier une
classe ou une interface :

public __construct(Moteur $engine) { $this->_moteur = $engine ; }


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Luc
> ...
Étant donné que php n'est pas typé, on peut passer n'importe quoi au
constructeur: un entier, un tableau ou un autre type d'objet...



Je viens de lire que l'on peut typer les classes.

Le constructeur de Voiture deviendrait alors

public function __construct( Moteur $moteur ) {
...
}

On mentionne dans la doc que le typage de paramètre ne fonctionne
qu'avec les variables de type object et array.
Le typage avec les types traditionnels, tels que int et string, n'est
pas supporté.

http://ch2.php.net/language.oop5.typehinting


Pour plus de robustesse, on pourrait développer les classes Int et
String...

J'imagine que de telles classes existent :-)


Merci de vos conseils et opinions.



On n'est jamais aussi bien bien servi que par soi-même :-)
Avatar
Bruno Desthuilliers
Luc a écrit :
Bonjour,

J'aimerais savoir si c'est courant de vérifier la nature d'un objet en
php.

Supposons que j'ai une classe Voiture ayant un membre privé _moteur.

Lors de la création d'une voiture, on doit lui passer un objet Moteur
en paramètre.

Étant donné que php n'est pas typé, on peut passer n'importe quoi au
constructeur: un entier, un tableau ou un autre type d'objet...

Dans la classe voiture si je fais $this->_moteur->arreter() et que
_moteur est un entier, on devine la catastrophe.



Heu... Une erreur d'exécution, certes, mais de là à parler de
"catastrophe", c'est peut-être exagéré. A moins bien sûr que ton code ne
gère une fusée, une centrale nucléaire ou autre, mais là j'ai comme un
doute... Les erreurs de typage peuvent être "catastrophiques" dans un
langage sans vérification de type à l'exécution, surtout quand ce
langage permet d'accéder directement à la mémoire. Ce n'est pas le cas ici.

Donc, dans le constructeur, je me dis que je devrais vérifier si je
reçois bien un moteur avec instanceOf.



Ce qui implique qu'un objet implémentant l'interface "Moteur" mais
n'étant pas instance d'une classe dérivée de Moteur ne sera pas accepté.
Par ailleurs, le fait qu'une classe hérite d'une autre (correction
structurelle) n'implique pas qu'elle implémente *correctement*
l'interface de la classe parent (correction sémantique). Par exemple,
une sous-classe de Moteur pourrait implémenter "arreter" de façon à
vider la base de données et envoyer un mail d'insulte à tes clients.

Cependant, je trouve que ça alourdit le code et me dis que c'est au
"propriétaire" de la voiture de lui fournir un moteur valide.



C'est généralement la logique qu'on utilise dans un langage à typage
dynamique. Après, il ne faut pas confondre règle générale et
circonstances particulières, donc c'est à toi de décider de l'option
préférable en fonction du contexte. Ici, la question est surtout de
savoir qui instancie ta classe Voiture, et quelles sont les chances
qu'un paramètre incorrect soit passé. Si c'est dans ton code à toi que
personne d'autre n'y met le nez, il est peu probable que tu t'emmêles à
ce point les pinceaux. Si c'est une API destinée à être étendue par des
centaines de développeurs inconnus (genre Facebook par exemple), il eput
être bon d'être un peu plus restrictif.

Mes deux centimes...
Avatar
Luc
On Jul 7, 4:32 am, Bruno Desthuilliers <bruno.
wrote:

> Dans la classe voiture si je fais $this->_moteur->arreter() et que
> _moteur est un entier, on devine la catastrophe.

Heu... Une erreur d'exécution, certes, mais de là à parler de
"catastrophe", c'est peut-être exagéré. A moins bien sûr que ton code ne
gère une fusée, une centrale nucléaire ou autre, mais là j'ai comme un
doute... Les erreurs de typage peuvent être "catastrophiques" dans un
langage sans vérification de type à l'exécution, surtout quand ce
langage permet d'accéder directement à la mémoire. Ce n'est pas le cas ici.




Tout est relatif :-)

> Donc, dans le constructeur, je me dis que je devrais vérifier si je
> reçois bien un moteur avec instanceOf.

Ce qui implique qu'un objet implémentant l'interface "Moteur" mais


... <skip>
Si c'est une API destinée à être étendue par des
centaines de développeurs inconnus (genre Facebook par exemple), il eput
être bon d'être un peu plus restrictif.




Merci beaucoup de m'avoir fait part de vos commentaires, c'est très
apprécié.

Luc