When you start your project with this framework, you will note that all your Controllers created via
php artisan make:controller extends a base application controller, located in
App\Http\Controllers\Controller. This class offers a complete boilerplate to create your Controller without having to guess what to include, and from where.
If that wasn’t enough, this class also extends another class,
Illuminate\Routing\Controller, which is an abstract class.
And sometimes, you don’t need to even extend them. Let’s start with the bottom of this rabbit hole.
The Base Controller
Laravel comes with an abstract class called Controller, which we can consider like the “Base Controller”.
This class has some useful methods through its traits and that we can resume in the following:
- Middleware functionality
- Calling a method inside the Controller
The first is pretty obvious, since is common knowledge to use the
$this->middleware() method inside the
__construct() method to let the middlewares handle the Request before (or after) it hits the target Controller method.
The second is not so obvious. It exists for dispatching the Request through the associated Controller and Method defined in your routes. We can see that this is done by the
dispatch() method in the
And what do you know. A quick glance on that code tell us that if the method
callAction doesn’t exists, it will dynamically try to call the method name, and if the
getMiddleware() method doesn’t exists, it assumes the Controller doesn’t register any middleware.
The utility of this method depends on what you want to do. For example, you can do something before effectively calling the method in your controller, but after the controller is instantiated and the middleware list executed.
The Application Controller
Next, we move up to the “Application Controller”, which is a handy class created by default to allow you access to some useful tools out-of-the-box. Let’s see what they are.
This trait is in charge of adding methods to authorize the Request before it further processing. This is documented as a Authorization Controller Helper.
If you’re totally not using the authorization helpers in your Controller, like when using auto-discovering of Policies or Gates, use seems like a safe bet to not use this trait.
This trait is very lean: it’s only has two methods that saves you resolving the Dispatcher service from the Service Container.
This allows you to dispatch a Job using this style:
public function dispatchMe(Request $request)
$this->dispatch(new ProcessPodcast); $this->dispatchNow(new SavePodcast);
Personally I consider this trait rather useless, but some I think is there for compatibility reasons. In any case, there is no harm or noticeable performance impact in doing this in your code.
This one is another helper trait that allows you to validate the incoming data. You are free on how to invoke a Validator instance, but this has handy methods like validating an already instanced Validator, or using a custom “bag of errors” instead of the default one.
This may be unnecessary in some escenarios. If you are using basic logic, consider using the
validate() helper method of the
$request instance in your Controller, which offers a quick way to validate what’s coming. If not, you may want to use these methods.
Then, it’s necessary or not?
Short answer: it’s not, as long your Controller is simple.
For example, you can make a “vanilla” Controller that is just a plain class that doesn’t use middlewares, authorization, dispatching, nor validation helpers. If that’s the case, you’re done. Or you can extend the default
Illuminate\Routing\Controller and set some middlewares for selected methods.
This also applies on Invokable Controllers. No need to extend your Application Controller, or even the Base Controller at all.
Personally I haven’t found noticeable performance impact when using OPCache between a fully-extended Controller and a simple class, doing exactly the same. But you do you, and make benchmarks in case it does impact your system.