web-dev-qa-db-ja.com

Laravelミドルウェアがコントローラーに変数を返す

ユーザーがページを表示できるかどうかを判断するために、ユーザーのアクセス許可チェックを実行しています。これには、最初にミドルウェアを介して要求を渡すことが含まれます。

私が抱えている問題は、データをビュー自体に返す前に、ミドルウェアとコントローラーで同じデータベースクエリを複製していることです。

セットアップの例を次に示します。

-routes.php

Route::get('pages/{id}', [
   'as' => 'pages',
   'middleware' => 'pageUser'
   'uses' => 'PagesController@view'
]);

-PageUserMiddleware.php(クラスPageUserMiddleware)

public function handle($request, Closure $next)
    {
        //get the page
        $pageId = $request->route('id');
        //find the page with users
        $page = Page::with('users')->where('id', $pageId)->first();
        //check if the logged in user exists for the page
        if(!$page->users()->wherePivot('user_id', Auth::user()->id)->exists()) {
            //redirect them if they don't exist
            return redirect()->route('redirectRoute');
        }
        return $next($request);
    }

-PagesController.php

public function view($id)
{
    $page = Page::with('users')->where('id', $id)->first();
    return view('pages.view', ['page' => $page]);
}

ご覧のとおり、ミドルウェアとコントローラーの両方でPage::with('users')->where('id', $id)->first()が繰り返されています。複製しないように、一方から他方にデータを渡す必要があります。

65
Alex

(Laravel 5.xで)これを行う正しい方法は、カスタムプロパティをattributesプロパティに追加することだと思います。

ソースコードのコメントから、カスタムパラメータに属性が使用されていることがわかります。

 /**
 * Custom parameters.
 *
 * @var \Symfony\Component\HttpFoundation\ParameterBag
 *
 * @api
 */
public $attributes;

したがって、これを次のように実装します。

$request->attributes->add(['myAttribute' => 'myValue']);

その後、次を呼び出して属性を取得できます。

\Request::get('myAttribute');

または、laravel 5.5+のリクエストオブジェクトから

 $request->get('myAttribute');
108
Gaz_Edge

カスタム要求パラメーターの代わりに、制御の反転パターンに従って、依存性注入を使用できます。

ミドルウェアで、Pageインスタンスを登録します。

app()->instance(Page::class, $page);

次に、コントローラーにPageインスタンスが必要であることを宣言します。

class PagesController 
{
    protected $page;

    function __construct(Page $page) 
    {
        $this->page = $page;
    }
}

Laravelは依存関係を自動的に解決し、ミドルウェアでバインドしたPageインスタンスを使用してコントローラーをインスタンス化します。

20
crishoj

laravel> = 5では、ミドルウェアで$request->mergeを使用できます。

public function handle($request, Closure $next)
{

    $request->merge(array("myVar" => "1234"));

    return $next($request);
}

そしてコントローラーで:

public function index(Request $request)
{

    $myVar = $request->instance()->query('myVar');
    ...
}
15
Vinicius

ミドルウェアからコントローラーにデータを渡すことができた場合、Laravelのドキュメントにあるはずです。

this および this をご覧ください。

つまり、ミドルウェアに渡されるリクエストオブジェクトにデータをピギーバックできます。 Laravel認証ファサードもそれを行います。

したがって、ミドルウェアには次のものがあります。

$request->myAttribute = "myValue";
6
Noman Ur Rehman

上記のlaravel 5.3.xのコメントの1つで述べたように

$request->attributes->add(['key => 'value'] ); 

動作しません。しかし、ミドルウェアでこのような変数を設定すると動作します

$request->attributes->set('key', 'value');

コントローラーでこれを使用してデータを取得できました

$request->get('key');
5
Tariq Khan

ララヴェル5.7

// in Middleware register instance
app()->instance('myObj', $myObj);

そして

// to get in controller just use the resolve helper
$myObj = resolve('myObj');

それは非常に簡単です:

ミドルウェアコードは次のとおりです。

public function handle($request, Closure $next)
{

    $request->merge(array("customVar" => "abcde"));

    return $next($request);
}

ここにコントローラーコードがあります:

$request->customVar;
3
Ashfaq Muhammad

$ requestは配列なので、配列に値とキーを追加するだけで、コントローラーでこのキーを使用して$ requestを取得できます。

$ request ['id'] = $ id;

2
Durgesh Pandey

Webサイトにデータベースから取得されるcmsページがあり、laravelアプリケーションのすべてのページのヘッダーブロックとフッターブロックにタイトルを表示する場合は、ミドルウェアを使用します。ミドルウェアで以下のコードを記述します。

namespace App\Http\Middleware;

use Closure;

use Illuminate\Support\Facades\DB;

public function handle($request, Closure $next)
{    

$data = DB::table('pages')->select('pages.id','pages.title')->where('pages.status', '1')->get();

\Illuminate\Support\Facades\View::share('cms_pages', $data);

return $next($request);

}

次に、header.blade.phpとfooter.blade.phpに移動し、以下のコードを記述してcmsページのリンクを追加します。

<a href="{{ url('/') }}">Home</a> | 

@foreach ($cms_pages as $page) 

<a href="{{ url('page/show/'.$page->id) }}">{{ $page->title }}</a> | 

@endforeach

<a href="{{ url('contactus') }}">Contact Us</a>

すべてに感謝し、コードをお楽しみください:)

2
Kamlesh

次の方法でRequest-objectに値を追加できました。

$request->attributes->set('key', 'value');

後でそれらを取得するには:

$request->attributes->get('key');

これは、 laravels Request extends symfonys Request 属性のタイプが- $ attributes " ParameterBag つまり カスタムパラメータ を保持することを目的としています。

これは、後続のミドルウェア、コントローラー、またはリクエストオブジェクトにアクセスできる他の場所にデータを渡すためのベストプラクティスであると思います。

Laravel 5.6でテストしましたが、おそらく他のバージョンでも動作します。

1
suud

私は英語を話せないので、可能性のあるエラーのために申し訳ありません。

これにはIoCバインディングを使用できます。ミドルウェアでは、$ pageインスタンスをバインドするためにこれを行うことができます。

\App::instance('mi_page_var', $page);

その後、コントローラーでそのインスタンスを呼び出します。

$page = \App::make('mi_page_var');

App :: instanceはクラスを再インスタンス化せず、代わりに以前にバインドしたインスタンスを返します。

1
Carlos Porter