【问题标题】:Laravel Request: it's correct injecting Request directly in the controller constructor?Laravel 请求:直接在控制器构造函数中注入请求是正确的吗?
【发布时间】:2016-08-17 13:38:28
【问题描述】:

在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...

【问题讨论】:

  • 如果有master/children请求怎么办?哪一个将被注入构造函数?为此(为了区分),symfony 建议注入请求堆栈服务,而不是 Request 本身。
  • “主/子请求”是什么意思?我用谷歌搜索了它,但仍然不清楚......
  • 在小应用程序中这是可以的。但是在未来的大型应用程序中,您需要将验证和授权与控制器分开。你会面临很多问题
  • @TortelliEngineer 您可以在代码中发出子请求。下面是例子:symfony.com/doc/current/templating/embedding_controllers.html 如果你愿意,我不知道哪个 Request 对象会被注入到构造函数中。
  • @KmasterYC 谢谢!我知道最好将验证放在其他地方,这只是请求的使用示例

标签: php laravel laravel-5 controller


【解决方案1】:

我一直在使用相同的技术来保护我的所有资源控制器路由与请求(例如检查登录的用户是否有权访问此资源)

但是,从 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;
    }
}

【讨论】:

    【解决方案2】:

    如果您的控制器BananaController 中的所有或几乎所有方法都使用Request 类,则注入依赖项的最常见方法是通过类的构造函数,如您的示例所示。

    使用构造函数注入有几个优点:

      1234563 >
    • 构造函数只在对象创建时被调用一次,因此您可以确保在对象的生命周期内依赖关系不会改变。

    请注意,这些优点确实意味着构造函数注入不适用于处理可选依赖项。与类层次结构结合使用也更加困难:如果一个类使用构造函数注入,那么扩展它并覆盖构造函数就会有问题。

    【讨论】:

    • 所以没关系!并非所有方法都使用它,但绝大多数方法都使用它!此外,在构造函数中,我还注入了一个 DataRepository 对象,该对象需要 Request 来检查经过身份验证的用户......但仅用一个问题来解释有点复杂。
    • 我喜欢好故事,但我是一名程序员,所以我期待代码但没有找到,所以我给自己找了一个枕头,躺下,蜷缩起来,开始哭泣。
    【解决方案3】:

    如果你使用构造函数来验证或授权你不能再使用php artisan route:list..所以最好通过route model binding得到你需要的东西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2021-05-20
      • 2023-04-09
      相关资源
      最近更新 更多