Laravel Request:直接在控制器构造函数中注入 Request 是正确的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38998282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Request: it's correct injecting Request directly in the controller constructor?
提问by TortelliEngineer
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?
在Laravel Controller中,如果所有的函数都使用Request,那么直接在构造函数中注入Request而不是函数是正确的吗?
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 :-)
放轻松,关于stackoverflow的第一个问题:-)
[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...
采纳答案by Yosvel Quintero Arguelles
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.
如果您的控制器BananaController
中的所有或几乎所有方法都使用Request
该类,则注入依赖项的最常见方法是通过类的构造函数,如您的示例所示。
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.
请注意,这些优点确实意味着构造函数注入不适合处理可选依赖项。与类层次结构结合使用也更加困难:如果一个类使用构造函数注入,那么扩展它并覆盖构造函数就会成为问题。
回答by elkbullwinkle
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.
然而,从 Laravel 5.3 开始,控制器构造函数现在在中间件执行之前运行,它实际上破坏了请求中的路由模型绑定。
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.
因此,如果您将请求直接注入到控制器方法中,例如在 Laravel 文档中,并且如果您将任何模型绑定到您的路由,它将很好地解决它,但是如果您在控制器构造函数中注入您的请求并尝试访问您的模型像下面这样的请求 - 它只会返回资源 ID 而不是模型。
//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;
}
}
回答by ghazyy
if you use construct function to validate or authorize you can not use php artisan route:list
anymore.. so it is better to get what you need through route model binding
如果你使用构造函数来验证或授权你就不php artisan route:list
能再使用了..所以最好通过路由模型绑定来获得你需要的东西