MISE À JOUR : PHP 7.4 prend désormais en charge la covariance et la contravariance, ce qui résout le problème majeur soulevé dans cette question.
J'ai rencontré un problème avec l'utilisation de l'indication de type de retour dans PHP 7. Je crois comprendre que l'indication : self
signifie que vous avez l'intention qu'une classe d'implémentation se renvoie elle-même. Par conséquent, j'ai utilisé : self
dans mes interfaces pour indiquer cela, mais lorsque j'ai essayé d'implémenter réellement l'interface, j'ai eu des erreurs de compatibilité.
Ce qui suit est une simple démonstration du problème que j'ai rencontré:
interface iFoo
{
public function bar (string $baz) : self;
}
class Foo implements iFoo
{
public function bar (string $baz) : self
{
echo $baz . PHP_EOL;
return $this;
}
}
(new Foo ()) -> bar ("Fred")
-> bar ("Wilma")
-> bar ("Barney")
-> bar ("Betty");
Le résultat attendu était:
Fred Wilma Barney Betty
Ce que j'obtiens en fait, c'est:
Erreur fatale PHP: Déclaration de Foo :: bar (int $ baz): Foo doit être compatible avec iFoo :: bar (int $ baz): iFoo dans test.php à la ligne 7
Le truc est que Foo est une implémentation d'iFoo, donc pour autant que je sache, l'implémentation doit être parfaitement compatible avec l'interface donnée. Je pourrais probablement résoudre ce problème en modifiant soit l'interface, soit la classe d'implémentation (ou les deux) pour renvoyer une indication de l'interface par son nom au lieu de l'utiliser self
, mais je crois comprendre que cela self
signifie sémantiquement "renvoyer l'instance de la classe sur laquelle vous venez d'appeler la méthode ". Par conséquent, le changer pour l'interface signifierait en théorie que je pourrais retourner n'importe quelle instance de quelque chose qui implémente l'interface lorsque mon intention est que l'instance invoquée est ce qui sera retourné.
Est-ce un oubli de PHP ou est-ce une décision délibérée de conception? Si c'est le premier, y a-t-il une chance de le voir corrigé en PHP 7.1? Si ce n'est pas le cas, quelle est la manière correcte de renvoyer en indiquant que votre interface s'attend à ce que vous retourniez l'instance sur laquelle vous venez d'appeler la méthode pour le chaînage?