Overriding a method implemented in a (used) trait

Published 6 months ago by miwal

The trait Illuminate\Foundation\Auth\RegistersUsers contains the following method (I copy it exactly):

    /**
     * The user has been registered.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  mixed  $user
     * @return mixed
     */
    protected function registered(Request $request, $user)
    {
        //
    }

The trait is used in RegisterController, in Http/Controllers/Auth

As above the trait contains the above method with an empty method body. Obviously we don't want to change this trait in the framework code in vendor/.

In a video, what Jeff did was implement the method in RegisterController.

I just wanted to get something clear: a trait is a way of doing multiple inheritance, it's obviously not an interface.

In php, if a class uses a trait, and it implements a method that is also implemented in the (multiple inheritance...) trait, do we know for a fact that the method body in the class itself will take precedence over the same method in the trait?

Is that the behaviour being relied upon here?

Jeff doing the above is at 1:20 here: https://laracasts.com/series/lets-build-a-forum-with-laravel/episodes/73

Best Answer (As Selected By miwal)
ottoszika

Whenever you are "overriding" a trait method, it will take precedence over the trait's one. Also, you can extend the functionality (like calling the parent method in inheritance and adding some extra stuffs) by aliasing:

trait RegistersUsers
{
    protected function registered(Request $request, $user)
    {
        echo 'Registered';   // Assuming this was originally in trait.
    }
}
class RegisterController
{
    use RegistersUsers {
        registered as traitRegistered;
    }

    protected function registered(Request $request, $user)
    {
        $this->traitRegistered();
        echo 'Welcome ' . $user->name;
    }
}

Note: Traits are not multiple inheritance. They are a code reuse mechanism, often called mixins in other languages.

ottoszika

Whenever you are "overriding" a trait method, it will take precedence over the trait's one. Also, you can extend the functionality (like calling the parent method in inheritance and adding some extra stuffs) by aliasing:

trait RegistersUsers
{
    protected function registered(Request $request, $user)
    {
        echo 'Registered';   // Assuming this was originally in trait.
    }
}
class RegisterController
{
    use RegistersUsers {
        registered as traitRegistered;
    }

    protected function registered(Request $request, $user)
    {
        $this->traitRegistered();
        echo 'Welcome ' . $user->name;
    }
}

Note: Traits are not multiple inheritance. They are a code reuse mechanism, often called mixins in other languages.

miwal
miwal
6 months ago (44,340 XP)

@ottoszika excellent answer, thank you.

Please sign in or create an account to participate in this conversation.