In a Laravel Controller, if all the functions use Request, it's correct to inject the Request directly in the constructor instead of the function?
The code below works, I was just wondering if it's correct and if it has side effects...
class BananaController extends Controller
{
protected $request; // request as an attribute of the controllers
public function __construct(Request $request)
{
$this->middleware('auth');
$this->request = $request; // Request becomes available for all the controller functions that call $this->request
}
public function store()
{
$this->validate($this->request, [
'text' => 'required',
]);
// I save the banana attributes and the controller continues...
Go easy on me, first question on stackoverflow ever :-)
[ADDENDUM] To be clear, the "conventional" code would be:
class BananaController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function store(Request $request)
{
$this->validate($request, [
'text' => 'required',
]);
// I save the banana attributes and the controller continues...
I have been using the same technique to protect all my resource controller routes with the request (for instance to check if the logged user is authorised to access this resource)
However, since Laravel 5.3 the controller constructors now run before middleware get executed and it actually broke route model binding inside the request.
So if you inject a request directly to a controller method, like in Laravel docs and if you have any model bound to you route it would resolve it fine, but if you inject your request in the controller constructor and try to access your model within the request like below - it will return just the resource id instead of the model.
//Route service provider
Route::model('resource', MyModel::class);
//Request class
public function authorize()
{
//We expect to get a resource or null
//But now it just returns the resource id
if (!is_null($this->resource))
{
return $this->resource->createdBy->id == $this->getLoggedUser()->id;
}
}
If all or almost of the methods in your controller BananaController
are using the Request
class, the most common way to inject dependencies is via a class's constructor as shown in your example.
There are several advantages to using constructor injection:
If the dependency is a requirement and the class cannot work without it then injecting it via the constructor ensures it is present when the class is used as the class cannot be constructed without it.
The constructor is only ever called once when the object is created, so you can be sure that the dependency will not change during the object's lifetime.
Note that these advantages do mean that constructor injection is not suitable for working with optional dependencies. It is also more difficult to use in combination with class hierarchies: if a class uses constructor injection then extending it and overriding the constructor becomes problematic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With