在Laravel Controller中,如果所有函数都使用Request,那么直接在构造函数而不是函数中注入Request是否正确?
以下代码有效,我只是想知道它是否正确以及是否有副作用......
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...
对我来说很容易,有关stackoverflow的第一个问题: - )
[ADDENDUM]要清楚,"传统"代码是:
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...
答案 0 :(得分:4)
我一直在使用相同的技术来保护我的所有资源控制器路由和请求(例如,检查记录的用户是否有权访问此资源)
然而,由于Laravel 5.3控制器构造函数现在在中间件执行之前运行,并且它实际上打破了请求中的路由模型绑定。
因此,如果您直接向控制器方法注入请求,例如在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;
}
}
答案 1 :(得分:3)
如果控制器BananaController
中的所有或几乎所有方法都使用Request
类,则注入依赖项的最常用方法是通过类的构造函数,如示例所示。
使用构造函数注入有几个优点:
如果依赖是一个需求,并且没有它就无法工作,那么通过构造函数注入它可以确保在使用类时它就存在,因为没有它就无法构造类。
构造函数只在创建对象时被调用一次,因此您可以确保在对象的生命周期内依赖关系不会发生变化。
请注意,这些优点确实意味着构造函数注入不适合使用可选的依赖项。与类层次结构结合使用也更加困难:如果一个类使用构造函数注入,那么扩展它并覆盖构造函数就会出现问题。
答案 2 :(得分:0)
如果您使用构造函数进行验证或授权,则无法再使用php artisan route:list
。因此,最好通过route model binding来获得所需的内容