LaravelのMiddleware覚書。
今回はviewにアクセス日時を表示するViewDateMiddlewareを作成します。
Middleware作成用のartisanコマンドが用意されているのでそれを使います。
引数にミドルウェア名を渡せばokです。
php artisan make:middleware ミドルウェア名
$ 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
が作成されます。
$ php artisan make:middleware ViewDateMiddleware
Middleware created successfully.
自動生成されたMiddlewareにはhandle関数のみ定義されています。
第一引数にRequest, 第二引数にClosureが渡されます。Requestはhttpリクエストでinput値等が取得できます。
Closureを実行することで次のMiddlewareが実行されます。
Controllerロジックより前に処理を入れたい場合は$next($request)
より前にコードを記述してください。
Controllerロジックの後に処理を入れたい場合は$next($request)
より後ろにコードを記述してください。
<?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を引数に指定します。
<?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で使える変数を定義できます。
public function handle($request, Closure $next)
{
$this->view->share('access_date', time());
return $next($request);
}
index.blade.php等のviewファイルで {{ $access_date }}
で使えます。
{{ $access_date }}
そしてブラウザで見てみるとエラーがでました。
Undefined variableなのでaccess_date変数の定義に失敗しています。
Middlewareはlaravelライフサイクルの中で読み込まれるようkernelやroute, controllerの中で指定する必要があります。
kernelにはMiddlewareを指定する箇所は3箇所あります。
・$middleware
全てのhttp通信で処理されるミドルウェアを追加
・$middlewareGroups
webやapi等の特定routeGroupで使用するミドルウェアを追加
・$routeMiddleware
ミドルウェアのalias名を指定できる。個々のrouteでalias名を使ってmiddlewareを指定できる。
今回は全てのwebリクエストで読み込まれるようにしたいのでkernelのmiddlewareGroupsに追記します。
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
middlewareに引数を渡す
routeで個別にmiddlewareを指定する際にmiddlewareに引数を渡せます。
先ほどのmiddlewareを改造し、routeごとに時刻フォーマットを指定できるようにします。
まずはkernel.phpの$middlewareGroupsに追記したmiddlewareを$routeMiddlewareに移動させます。
viewData
aliasで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
を引数にするように指定しました。
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
にアクセスすると
http://127.0.0.1:8000/viewDate-Ym
にアクセスすると
と表示されるようになりました。