0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravel Middlewareを自作する

Posted at

LaravelのMiddleware覚書。
今回はviewにアクセス日時を表示するViewDateMiddlewareを作成します。

Middleware作成用のartisanコマンドが用意されているのでそれを使います。
引数にミドルウェア名を渡せばokです。
php artisan make:middleware ミドルウェア名

help
$ php artisan make:middleware --help
Description:
  Create a new middleware class

Usage:
  make:middleware <name>

Arguments:
  name                  The name of the class

以下のコマンドでapp/Http/Middleware/ViewDateMiddleware.phpが作成されます。

ViewDateMiddleware.phpを作成
$ php artisan make:middleware ViewDateMiddleware
Middleware created successfully.

自動生成されたMiddlewareにはhandle関数のみ定義されています。
第一引数にRequest, 第二引数にClosureが渡されます。Requestはhttpリクエストでinput値等が取得できます。
Closureを実行することで次のMiddlewareが実行されます。
Controllerロジックより前に処理を入れたい場合は$next($request)より前にコードを記述してください。
Controllerロジックの後に処理を入れたい場合は$next($request)より後ろにコードを記述してください。

ViewDateMiddleware.php
<?php

namespace App\Http\Middleware;

use Closure;

class ViewDateMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

MiddlewareはApplicationサービスコンテナによってインスタンス化されるため、コントラクタ引数に任意のクラスを指定することでDIされます。
今回はviewにアクセス日時を表示できる変数を渡すのでViewのFactoryを引数に指定します。

ViewDateMiddleware
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\View\Factory;

class ViewDateMiddleware
{

    private $view;

    public function __construct(Factory $view)
    {
        $this->view = $view;
    }

  省略
}

handle関数内でFactoryのshare関数を使うことでviewで使える変数を定義できます。

ViewDateMiddleware
    public function handle($request, Closure $next)
    {
        $this->view->share('access_date', time());
        return $next($request);
    }

index.blade.php等のviewファイルで {{ $access_date }} で使えます。

index.blade.php
{{ $access_date }}

そしてブラウザで見てみるとエラーがでました。
Undefined variableなのでaccess_date変数の定義に失敗しています。
スクリーンショット 2020-04-09 1.45.31.png

Middlewareはlaravelライフサイクルの中で読み込まれるようkernelやroute, controllerの中で指定する必要があります。
kernelにはMiddlewareを指定する箇所は3箇所あります。
・$middleware
全てのhttp通信で処理されるミドルウェアを追加

・$middlewareGroups
webやapi等の特定routeGroupで使用するミドルウェアを追加

・$routeMiddleware
ミドルウェアのalias名を指定できる。個々のrouteでalias名を使ってmiddlewareを指定できる。

今回は全てのwebリクエストで読み込まれるようにしたいのでkernelのmiddlewareGroupsに追記します。

App/Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\ViewDateMiddleware::class, //ここに追加
        ],

        'api' => [
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

これでミドエルウェアが実行されてviewでaccess_date変数が使用できるようになりました。
↓結果html
スクリーンショット 2020-04-09 2.26.26.png

middlewareに引数を渡す

routeで個別にmiddlewareを指定する際にmiddlewareに引数を渡せます。
先ほどのmiddlewareを改造し、routeごとに時刻フォーマットを指定できるようにします。

まずはkernel.phpの$middlewareGroupsに追記したmiddlewareを$routeMiddlewareに移動させます。
viewDataaliasでmiddlewareを指定できるようにしました。

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'ViewDate' => \App\Http\Middleware\ViewDateMiddleware::class, //追加
    ];

続いてrouteでmiddlewareを指定します。
middleware名:引数のフォーマットで指定することでmiddlewareに引数を渡すことができます。
viewDate-YmdにアクセスしたらY/m/dを、
viewDate-YmにアクセスしたらY/mを引数にするように指定しました。

web.php
Route::get('/viewDate-Ymd', function() {
    return view('index');
})->middleware('viewDate:Y/m/d');


Route::get('/viewDate-Ym', function () {
    return view('index');
})->middleware('viewDate:Y/m');

これで
http://127.0.0.1:8000/viewDate-Ymd
にアクセスすると
スクリーンショット 2020-04-09 2.43.29.png

http://127.0.0.1:8000/viewDate-Ym
にアクセスすると
スクリーンショット 2020-04-09 2.43.43.png

と表示されるようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?