今回は、ミドルウェアの使い方について解説していきます。
参考書
ミドルウェアとは
ミドルウェアとは、コントローラとは別に「指定のアドレスにリクエストが送られてきたら、自動的に何らかの処理をおこなう」というものになります。
ミドルウェアが動作するタイミングは、リクエストがコントローラのアクションに届く前と、アクションが実行されレスポンスがクライアントに届く前になります。

ミドルウェアの作成
コマンドラインで以下を実行します。
php artisan make:middleware SampleMiddleware
ミドルウェアは「app/Http/Middleware」の中に入っていますので、作成した「SampleMiddleware」を開きましょう。
そして、SampleMiddleware クラスを以下のように記述します。
class SampleMiddleware
{
public function handle(Request $request, Closure $next)
{
$users = [
['name'=>'山田', 'mail'=>'yamada@sample.com'],
['name'=>'田中', 'mail'=>'tanaka@sample.com'],
['name'=>'鈴木', 'mail'=>'suzuki@sample.com'],
];
$request->merge(['users'=>$users]);
return $next($request);
}
}
併せてコントローラのアクションとテンプレートも一緒に書いておきます。
//コントローラ
public function index(Request $request) {
return view('sample.index',['users'=>$request->users]);
}
//テンプレート
@section('content')
<p>ここはcontentセクションです</p>
<ul>
@foreach($users as $user)
<li>{{$user['name']}} [{{$user['mail']}}]</li>
@endforeach
</ul>
@endsection
SampleMiddleware クラスの 「merge メソッド」は、新たな値を追加するためのものです。
$request->merge( 連想配列 ) とすることで、$request に「users」というデータを追加しています。
コントローラ側では、$request->users でデータを取り出すことができます。
そして、$next($request) では、Response インスタンスが返されます。
つまり、$next($request) が実行されると、コントローラのアクションが実行され、ページがレンダリングされてレスポンスが生成されます。
このレスポンスが $next($request) の戻り値となります。
そして、$next($request) がクライアントに渡されてブラウザに表示されるという流れになります。
ミドルウェアの登録とルートへの追記
作成したミドルウェアは登録する必要があります。
「app/Http/Kernel.php」を開き、$routeMiddleware という配列を見つけ、その中に以下を追加してください。
'sample' => \App\Http\Middleware\SampleMiddleware::class,
これでアプリケーションにミドルウェアを登録することができましたが、
「どのルートにアクセスしたときにどのミドルウェアを利用するのか」がまだ登録できていません。
これを設定するために「resources/routes/web.php」を開き、以下のように記述します。
use App\Http\Middleware\SampleMiddleware;//追加
Route::get('/sample', 'App\Http\Controllers\SampleController@index')
->middleware(SampleMiddleware::class);
このように、Route::get の後ろにメソッドチェーンでミドルウェアを追加することができます。
複数のミドルウェアを登録したい場合は、メソッドチェーンを連続で記述します。
これでルートにミドルウェアを登録できました。
ブラウザで確認すると以下のようになります。

ミドルウェアで後処理をする
ここまでで作ったサンプルでは、リクエストがコントローラのアクションに届く前にミドルウェアが「users データを生成して$request に追加する」という前処理をつくりました。
ここからは、コントローラが返したレスポンスに対してミドルウェアが行う後処理のつくり方をみていきます。
といってもそこまで難しくありません。
先ほどのサンプルでは後処理が必要なかったため、
return $next($request)
としてそのままクライアントに返していましたが、
後処理が必要な場合は
$response = $next($request)
のように一旦変数にいれ、必要な処理をおこなってから return で返します。
サンプルの作成
先にできあがった表示をお見せします。

まず前処理で「red, blue, green」という文字列をコントローラに渡し、
コントローラがその文字列をテンプレートに渡してレンダリングが完了しレスポンスが生成されたら、
ミドルウェアが後処理として、それぞれの色名にあったスタイルを与えてクライアントに返すという流れになります。
//ミドルウェア
class SampleMiddleware
{
public function handle(Request $request, Closure $next)
{
//前処理
$colors = [
['color'=>'red'],
['color'=>'blue'],
['color'=>'green'],
];
$request->merge(['colors'=>$colors]);
//後処理(colorスタイルを付与)
$response = $next($request);
$content = $response->content();
$pattern = '/<li>(.*)<\/li>/i';
$replace = '<li style="color: $1">$1</li>';
$content = preg_replace($pattern, $replace, $content);
$response->setContent($content);
return $response;
}
}
//コントローラのアクション
public function index(Request $request) {
return view('sample.index',['colors'=>$request->colors]);
}
//テンプレート
@section('content')
<p>ここはcontentセクションです</p>
<ul>
@foreach($colors as $color)
<li>{{$color['color']}}</li>
@endforeach
</ul>
@endsection
改めて処理の流れを確認すると、以下のようになります。
①クライアントからリクエストが送られる
②ミドルウェアの handle を実行
③上から順に前処理がおこなわれ、$next を実行
(複数のミドルウェアが設定されている場合、次のミドルウェアの handle を実行)
コントローラのアクションが呼び出される
④アクションが終わりページがレンダリングされ、生成されたレスポンスが $next の戻り値になる
⑤後処理をおこない、結果をクライアントに return

グローバルミドルウェアの登録
先ほどは特定のルートにミドルウェアを設定していましたが、全てのアクセスに対しミドルウェアを実行させたい場合はグローバルミドルウェアに登録します。
「app/Http/Kernel.php」を開き、$middleware という配列を見つけ、その中に以下を追加してください。
\App\Http\Middleware\SampleMiddleware::class,
これでグローバルミドルウェアに登録できたので、「web.php」のメソッドチェーンは不要になります。
Route::get('/sample', 'App\Http\Controllers\SampleController@index');
ミドルウェアのグループ登録
複数のミドルウェアをひとつにグループ化して扱うことができます。
「app/Http/Kernel.php」の中の、$middlewareGroups という配列を見つけ、その中に以下を追加してください。
'sample' => [
\App\Http\Middleware\SampleMiddleware::class,
//ミドルウェア2,
//ミドルウェア3,
// :
],
これで、「sample」というグループ名でミドルウェアをグループ登録できました。
グループをルートに設定するには以下のように記述します。
Route::get('/sample', 'App\Http\Controllers\SampleController@index')
->middleware('sample');
これで、「/sample」にアクセスしたときに「sample」という名前のミドルウェアグループが実行されるようになります。
今回は以上になります。
ご覧いただきありがとうございました(^^)
参考書
続きはこちら↓
コメント