Why and how to override Laravel’s built-in auth controller methods

Maybe like me you like to do things the ‘Laravel way’. So let’s say you’re still using the out-of-the-box Auth flow (can anyone recommend an easy, drop-in alternative?). You want to keep that flow without having to rewrite it, but you realise it doesn’t quite do everything you need.

However, as you’ll soon be aware, the logic for the full registration and login processes is fragmented. By the time you’ve followed the setup and got everything working, you find that your controllers are inheriting methods from Laravel core, but they don’t have all the functionality you want… but everyone knows you should never edit core files!

Never hack core — it’s a “crime against nature”

Perhaps the easiest example of this is the getLogin() controller method. It’s pretty simple: just load the right view.

But this method is “inherited” from the AuthenticatesAndRegistersUsers trait, which probably inherits from the AuthenticatesUsers trait, which is buried within Laravel’s core.

The thing is this isn’t “inheritance” in the old-fashioned sense of the word — you can’t just overwrite these methods and use parent::getLogin() to call the upstream method, benefiting from all of its functionality.

This will undoubtedly fail

Traits don’t exist in the same inheritance stack as extended classes — they’re more like class partials and any number of them can be combined within a class. In that context, it’s better to not think of it as inheritance, but more as appropriation; we’re appropriating the methods in the trait and placing them in the context of the class that uses them. So they’re not “inherited”; they exist as part of the definition of the class that uses them.

Thankfully, the traits functionality built into PHP offers a neat workaround that still allows us to call the originally-defined function (the one in the trait), whilst “extending” it with our own functionality. Here’s how:

Here’s the ‘right’ way to do this

As you can see, we’re basically aliasing the methods from the trait so that we’re not caught out for redefining methods. And then we can call the original method to still use that functionality. Beautiful. Thanks PHP devs!

It also shows great insight by Taylor and the other Laravel core devs — particularly with the focus on method chaining. Without it, my example wouldn’t even be possible. Great work folks!