yujiro's blog

エンジニアリング全般の事書きます

【Laravel5】Session flash が全く効かなくて焦った。

原因

Controller の__construct 内で Sessionを使いたいがために Http/Kernel.php

    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class
    ];

と記述しているのがまずかった。

その直下の

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

の部分にも StartSession を記述していたので、Session が上書きStartされていた。

なので、$middlewareGroups のほうのStartSessionコメントアウトした

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            //\Illuminate\Session\Middleware\StartSession::class, 
            //\Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

色々検索したけど、俺みたいに自分の蒔いた種で自爆した人はいなかったみたいで、結構時間かかってしまった。

ちなみに Laravel5.3よりまえのバージョンでは上記をしなくてもControllerの __construct 内でも Session を使えるらしい。

以下は彷徨った過程

Laravel5を使っていて、下記の様なコードを書いた。

Controller

return redirect('/mypage/edit')->with('msg', 'プロフィールを編集しました。');

View

@if (Session::has('msg'))
{{ Session::get('msg') }}
@endif

すごくシンプルなコードなんだけど、これが全く表示されなかった。

最初に試したのはコントローラでflashメソッドを利用した直後にSessionを表示させた。

\Session::flash('msg','Hey, You have a message to read');
dd(\Session::all());
return redirect('/mypage/edit');

ここにはsessionの値は入っている。 ということは redirect すると消えてしまうということか。

すぐさまGoogle先生に聞いてみて色々調べたら以下のページを見つけた。

laracasts.com

Best Answer に記載のあったコードを試した。

Route::group(['middleware' => ['web']], function () {

    Route::get('/a', function () {
        dd(session()->all());
        return view('welcome');
    });

    Route::get('/notify',function(){
        session()->flash('msg','Hey, You have a message to read');
        return redirect()->to('/a');
    });
});

上記を routes/web.php に記述して(ちょっと変えてます)、/notify にアクセスし、リダイレクト後に表示させている session の中をみたけど、 msg がなかった。


これは、もっとコアな部分に原因があるんだろう、ということで app/Providers/RouteServiceProvider.php とか app/Providers/AppServiceProvider.php とか app/Http/Kernel.php とか見直してやっと判明した。