I have a class that looks like this. I will also paste it below for reference:
<?php
trait T1
{
abstract protected function _doStuff();
}
trait T2
{
protected function _doStuff()
{
echo "Doing stuff in trait
";
}
}
class C
{
use T1 {
_doStuff as _traitDoStuff;
}
use T2 {
_doStuff as _traitDoStuff;
}
protected function _doStuff()
{
echo "Doing stuff in class
";
$this->_traitDoStuff();
}
}
Here's what's happening here:
-
T1::_doStuff()
is used, and aliased as_traitDoStuff()
. As per PHP docs, this does not rename the method, but only adds an alias. So at this point, both_doStuff()
and_traitDoStuff()
exist as abstract protected methods. -
T2::_doStuff()
is used, and aliased as_traitDoStuff()
. As per PHP docs, due to precedence, both are overridden by methods ofT2
. So at this point,T1::_doStuff()
no longer exists. Even if it would, it would be implemented byT2::_doStuff()
. -
C
implements_doStuff()
, which calls_traitDoStuff()
. At this point, regardless of which implementation of_doStuff()
is used, it is obvious that this method is implemented, so the contract defined byT1::_doStuff()
is satisfied, or doesn't exist.
And yet, when I run this, it gives the following error:
Fatal error: Class C contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (C::_doStuff)
As can be seen from 3v4l, this manifests everywhere from PHP 5.4 to 7.2, which kinda hints that this is not an early trait bug. Can somebody please explain this to me?
Update
Apparently, I just forgot to specify the method that I am aliasing, i.e. T1::_doStuff as _traitDoStuff
.