web-dev-qa-db-ja.com

Laravelリクエスト:コントローラコンストラクタにリクエストを直接挿入するのは正しいですか?

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の最初の質問:-)

[追記]明確にするために、「従来の」コードは次のようになります。

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

コントローラーのすべてまたはほとんどのメソッドBananaControllerRequestクラスを使用している場合、依存関係を注入する最も一般的な方法は、例に示すようにクラスのコンストラクターを使用することです。

コンストラクター注入を使用することには、いくつかの利点があります。

  • 依存関係が要件であり、それなしではクラスが機能しない場合、コンストラクターを介して依存関係を注入すると、クラスを使用しないとクラスを構築できないため、依存関係が存在することが保証されます。

  • オブジェクトが作成されるときにコンストラクターが呼び出されるのは一度だけなので、オブジェクトの存続期間中に依存関係が変更されないことを確認できます。

これらの利点は、コンストラクターの注入がオプションの依存関係の操作に適していないことを意味することに注意してください。また、クラス階層と組み合わせて使用​​することはより困難です。クラスがコンストラクター注入を使用する場合、それを拡張してコンストラクターをオーバーライドすることが問題になります。

3
Yosvel Quintero

同じ手法を使用して、すべてのリソースコントローラールートをリクエストで保護しています(たとえば、ログインしたユーザーがこのリソースへのアクセスを許可されているかどうかを確認するため)

ただし、Laravel 5.3以降、ミドルウェアが実行される前にコントローラーコンストラクターが実行され、実際にリクエスト内のルートモデルバインディングが破損しました。

したがって、Laravel docsのようにコントローラのメソッドにリクエストを直接挿入し、モデルにルーティングがバインドされている場合は、問題を解決できますが、コントローラにリクエストを挿入するとコンストラクターを使用して、以下のようなリクエスト内でモデルにアクセスしてみてください。モデルではなく、リソース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;
    }
}
4
elkbullwinkle