Reputation: 5889
Okay say the following straits are given:
trait Base
{
public function doSomething()
{
// Do fancy stuff needed in other traits
}
}
trait A
{
use Base;
public function foo()
{
// Do something
}
}
trait B
{
use Base;
public function bar()
{
// Do something else
}
}
and I like to implement a class now which uses both traits A
and B
:
class MyClass
{
use A, B;
}
PHP tells me it can't redefine function doSomething()
. What's the reason PHP is not able to detect that A
and B
share one and the same trait and don't copy it twice into MyClass
(is it a bug or a feature preventing me from writing unclean code)?
Is there a better solution for my problem then this workaround with which I ended up:
trait Base
{
public function doSomething()
{
// Do fancy stuff needed in other traits
}
}
trait A
{
abstract function doSomething();
public function foo()
{
// Do something
}
}
trait B
{
abstract function doSomething();
public function bar()
{
// Do something else
}
}
And then my class:
class MyClass
{
use Base, A, B;
}
Upvotes: 11
Views: 9094
Reputation: 17188
This has been fixed in PHP 7.3:
trait A
{
public function a(){}
}
trait B
{
use A;
}
trait C
{
use A;
}
class D
{
use B, C;
}
Results:
PHP 7.3+ Fine
PHP ^5|^7.2: Fatal error: Trait method a has not been applied, because there are collisions with other trait methods on D in /in/Z5GTo on line 18
Props to @Grzegorz that posted the link to the PHP bug, to an answer, but got deleted by vote. I tried to re-open it but couldn't.
Upvotes: 4
Reputation: 1328
You can resolve this conflict with "insteadof" like this:
class MyClass
{
use A, B {
A::doSomething insteadof B;
}
}
EDIT For more traits resolving conflicts can look like this:
class MyClass
{
use A, B, C, D {
A::doSomething insteadof B, C, D;
}
}
Upvotes: 15