Arvid
Arvid

Reputation: 1081

How to override a trait's method in abstract class?

I'm stuck into a problem with traits I can't solve on my own.

I have classes extending an abstract class (in my case these are several controller classes and an abstract class Controller, the used framework won't be important here, since this is a general PHP question…) that uses traits. I'd like to override a method defined in one of the traits. This only works as long as I define the method in my sub-classes but not in my abstract class.


So, this one works perfectly:

class MyController extends Controller
{
    use AnyTrait;

    public function anyMethodFromAnyTrait()
    {
        // override AnyTrait::anyMethodFromAnyTrait()
    }
}

I also know how to call the anyMethodFromAnyTrait method from AnyTrait by using as.

class MyController extends Controller
{
    use AnyTrait { AnyTrait::anyMethodFromAnyTrait as method }

    public function anyMethodFromAnyTrait()
    {
        // invoke AnyTrait::anyMethodFromAnyTrait()
        $this->method();
    }
}

Both work like a charm.


But my problem is a bit different.

When using the trait and defining the method in my abstract class I am not able to override the trait's method.

Assume the following controller class:

class MyController extends Controller
{
    public function anyAction()
    {
        // let's see what happens…
        $this->anyMethodFromAnyTrait();
    }
}

…and the abstract one that's extended by MyController:

abstract class Controller
{
    use AnyTrait

    public function anyMethodFromAnyTrait()
    {
        // do something different than AnyTrait
    }
}

…And this is what's not working at all. Whenever I call $this->anyMethodFromAnyTrait() within MyController the trait's method as implememented in AnyTrait will be invoked. The same named method in my abstract Controller will be ignored.

Therefore I only can override a trait's method in a concrete sub-class but not in an abstract class that is extended by that sub-class.

So the method definitions in traits get a higher priority by PHP than the same method definitions in abstract classes.

Do you know any workaround for that behaviour?

Upvotes: 2

Views: 1190

Answers (1)

devnull
devnull

Reputation: 608

One workaround would be to use the traits ONLY in the subclasses. PHP always prefers the trait methods over the "local" ones.

The reason why it works in subclasses is, that the trait method of the superclass is extended, not the trait usage itself.

Upvotes: 1

Related Questions