⊗ppOpTrMC 79 of 107 menu

Resolving Trait Method Conflicts in OOP in PHP

Since a single class can use multiple traits, we may encounter a problem that arises when two traits have methods with the same name.

In this case, PHP will throw a fatal error. To fix the situation, it will be necessary to resolve the name conflict explicitly. How this is done - let's see in practice.

Let's say we have two traits with the same method method:

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

Let's also say we have a class Test, using both of our traits. If we simply include both traits in our class, then PHP will throw an error because the traits have conflicting methods:

<?php // This code will throw an error! class Test { use Trait1, Trait2; // connecting traits } ?>

Let's resolve the name conflict of our traits. For this, there is a special operator insteadof. Using this operator, we will use the method method from the trait Trait1 instead of the same method from the trait Trait2:

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

As you can see, the syntax is as follows: first the trait name, then two colons, then the method name, then our operator insteadof and the name of the second trait.

Let's test it:

<?php class Test { use Trait1, Trait2 { Trait1::method insteadof Trait2; } public function __construct() { echo $this->method(); // will output 1, because it's the method from the first trait } } new Test; ?>

So, in our class, we specified that if the method method is used, it should be taken from the first trait. The opposite is also possible - take the method from the second trait:

<?php class Test { use Trait1, Trait2 { Trait2::method insteadof Trait1; } public function __construct() { echo $this->method(); // will output 2, because it's the method from the second trait } } new Test; ?>

In any case, if we specify to use the method of one trait, then the method of the second trait becomes unavailable. We can also use the method of the second trait by renaming it using the keyword as, like this:

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

If desired, you can also rename the method of the first 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(); // will output 3 } } new Test; ?>

Using the keyword as without defining the main method via insteadof is not allowed; this will throw an error:

<?php // This class will throw an error: class Test { use Trait1, Trait2 { Trait1::method as method1; Trait2::method as method2; } public function __construct() { echo $this->method1() + $this->method2(); } } new Test; ?>

Create 3 traits named Trait1, Trait2, and Trait3. Let the first trait have a method method that returns 1, the second trait - a method with the same name returning 2, and the third trait - a method with the same name, returning 3.

Create a class Test that uses all three traits we created. Create a method getSum in this class that returns the sum of the results of the methods from the connected traits.

byenru