⊗ppOpTrMC 79 of 107 menu

Résolution des conflits de méthodes de traits en POO en PHP

Comme une classe peut utiliser plusieurs traits, un problème peut survenir lorsque deux traits ont des méthodes homonymes.

Dans ce cas, PHP générera une erreur fatale. Pour corriger la situation, il faudra résoudre le conflit de noms explicitement. Comment cela se fait - voyons-le en pratique.

Supposons que nous ayons deux traits avec la même méthode method :

<?php trait Trait1 { private function method() { return 1; } } trait Trait2 { private function method() { return 2; } } ?>

Supposons que nous ayons également une classe Test, utilisant nos deux traits. Si nous connectons simplement les deux traits à notre classe, alors PHP générera une erreur, car les traits ont des méthodes conflictuelles :

<?php // Ce code générera une erreur ! class Test { use Trait1, Trait2; // connecter les traits } ?>

Résolvons le conflit de noms de nos traits. Pour cela, il existe un opérateur spécial insteadof. En utilisant cet opérateur, nous utiliserons la méthode method du trait Trait1 au lieu de la méthode du même nom du trait Trait2 :

<?php class Test { use Trait1, Trait2 { Trait1::method insteadof Trait2; } } new Test; ?>

Comme vous le voyez, la syntaxe est la suivante : d'abord le nom du trait, puis deux deux-points, puis le nom de la méthode, puis notre opérateur insteadof et le nom du second trait.

Vérifions :

<?php class Test { use Trait1, Trait2 { Trait1::method insteadof Trait2; } public function __construct() { echo $this->method(); // affichera 1, car c'est la méthode du premier trait } } new Test; ?>

Ainsi, dans notre classe, nous avons dit que si la méthode method est utilisée, alors il faut la prendre du premier trait. On peut aussi faire l'inverse - prendre la méthode du second trait :

<?php class Test { use Trait1, Trait2 { Trait2::method insteadof Trait1; } public function __construct() { echo $this->method(); // affichera 2, car c'est la méthode du second trait } } new Test; ?>

Dans tous les cas, si nous spécifions d'utiliser la méthode d'un trait, alors la méthode du second trait devient inaccessible. On peut aussi utiliser la méthode du second trait, en la renommant via le mot-clé as, comme ceci :

<?php class Test { use Trait1, Trait2 { Trait1::method insteadof Trait2; Trait2::method as method2; } public function __construct() { echo $this->method() + $this->method2(); // affichera 3 } } new Test; ?>

Si on le souhaite, on peut aussi renommer la méthode du premier trait :

<?php class Test { use Trait1, Trait2 { Trait1::method insteadof Trait2; Trait1::method as method1; Trait2::method as method2; } public function __construct() { echo $this->method1() + $this->method2(); // affichera 3 } } new Test; ?>

Utiliser le mot-clé as sans définir la méthode principale via insteadof est interdit, cela générera une erreur :

<?php // Cette classe générera une erreur : class Test { use Trait1, Trait2 { Trait1::method as method1; Trait2::method as method2; } public function __construct() { echo $this->method1() + $this->method2(); } } new Test; ?>

Créez 3 traits avec les noms Trait1, Trait2 et Trait3. Que le premier trait ait une méthode method renvoyant 1, le second trait - une méthode homonyme renvoyant 2, et le troisième trait - une méthode homonyme renvoyant 3.

Créez une classe Test utilisant les trois traits que nous avons créés. Créez dans cette classe une méthode getSum renvoyant la somme des résultats des méthodes des traits connectés.

azbydeenesfrkakkptruuz