こちらの記事は以下の書籍を参考に執筆しました
ミドルウェアの利用
ミドルウェアとは
指定のアドレスにリクエストが送られたら何らかの処理を行う仕組みのこと
/***************************/
//リクエスト
/***************************/
↓ ←ミドルウェア
/***************************/
//アクション
/***************************/
↓ ←ミドルウェア
/***************************/
//レスポンス
/***************************/
ミドルウェアの作成
php artisan make:middleware ミドルウェア名
これでHttp/Middleware
に作成される。
ここではHelloMiddlewareという名前で作る。
HelloMiddlewareクラス
作成されたHelloMiddlewareはなんのクラスも継承していない。
handleメソッドについて
これには1つだけメソッドがある。
以下のように定義されている。
public function handle($request, Closure $next)
{
//実行する処理
}
引数 | 説明 |
---|---|
$request | リクエスト情報を管理するRequestインスタンス |
$next | Closureクラスのインスタンス。 |
Closureは無名関クラスを表すクラス。
$nextはクロージャでこれを呼び出して実行すると
ミドルウェアからアプリケーションへと送られるリスエスト(Requestインスタンス)を作成できる。
$request->merge(配列)
public function handle($request, Closure $next)
{
$data=[
['name'=>'taro','mail'=>'taro@example.com'],
['name'=>'taro2','mail'=>'taro2@example.com'],
['name'=>'taro3','mail'=>'taro@3example.com'],
];
$request->merge(['data'=>$data]);
return $next($request);
}
mergeはフォーム送信で送られる値(input値)に値を追加できる。
dataという項目で$dataの内容が追加される。
コントローラ側では$request->data
で取り出せる。
その後ミドルウェアを登録する。
$routeMiddleware変数の最後に追記する。
'hello'=>\App\Http\Middleware\HelloMiddleware::class,
これで登録完了。
ミドルウェアの実行
次は利用するミドルウェアを呼び出す処理を書いていく。
//use App\Http\Middleware\HelloMiddleware;を追記
Route::get('hello', 'HelloController@index')->middleware(HelloMiddleware::class);
メソッドチェーンで追加していく。
連続して書くこともできる。
Route::get(...)->middleware(...)->middleware(...);
ビューとコントローラの修正
これでミドルウェアが/helloで動作するようになった。
次は変数$dataの動作を確認していく。
コントローラを修正する。
public function index(Request $request)
{
return view('hello.index',['data'=>$request->data]);
}
テンプレを修正する。
@section('content')
<p>ここが本文のコンテンツ</p>
<table>
@foreach($data as $item)
<tr>
<th>{{$item['name']}}</th><td>{{$item['mail']}}</td>
</tr>
@endforeach
</table>
@endsection
/helloにアクセスして確認してみる。
今後DBを使うようになるとミドルウェアがコントローラの負担を減らしてくれる。
リクエストとレスポンスの流れ
今回は「リクエスト」→「処理」の流れだったが
「処理」→「リクエスト」もできる。
つまりアクション後の処理も作成できる。
ミドルウェアのhandleメソッドのデフォルトはこうなっていた。
public function handle($request, Closure $next)
{
return $next($request);
}
引数として$requestが渡され、クロージャの戻り値がreturnで返されていた。
この$nextで返されるものはResponseインスタンスだ。
リスエストが送られてからクライアントにレスポンスが返されるまでの流れはこうだ。
- リクエストが送られる。
- ミドルウェアのhandleが呼びだされる
- $nextを実行する。複数のミドルウェアが設定されてるなら、次のミドルウェアのhandleが呼び出される。ないならコントローラのアクションが呼び出される。
- アクションメソッドが終わるとともにページがレンダリングされ、レスポンスが生成される。この生成されたレスポンスが$nextの戻り値。
- 返されたレスポンスがreturnで返され、クライアントへ返される。
前処理と後処理
この流れを理解するとコントローラの前と後でのミドルウェアの作成方法がわかる。
前処理
先もやったように、必要な処理をすべて実行してから$nextを実行してreturn
public function handle($request, Closure $next)
{
//処理を実行
return $next($request);
}
後処理
$nextを実行してレスポンスを受け取ってから処理を実行する。
処理が終わったら保管してあったレスポンスをreturn
public function handle($request, Closure $next)
{
$response=$next($request)
//処理を実行
return $response;
}
```>出典:[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)
## レスポンス操作
では後処理のサンプルを作っていく。
HelloMiddlewareクラスを修正
```php5
public function handle($request, Closure $next)
{
$response = $next($request);
$content = $response->content();
$pattern = '/<middleware>(.*)<\/middleware>/i';
$replace = '<a href="http://$1">$1</a>';
$content = preg_replace($pattern, $replace, $content);
$response->setContent($content);
return $response;
}
処理の流れ
$response = $next($request);
でコントローラのアクションが実行され、レスポンスが代入される。
$content = $response->content();
コンテンツを取得している。
その後正規表現で置換を行っている。
後はレスポンスにコンテンツを設定してreturn
$response->setContent($content);
return $response;
レスポンスへのコンテンツの設定にはsetContentメソッドを使う。
つぎはテンプレを修正
@section('content')
<p>ここが本文のコンテンツ</p>
<p>これは<middleware>google.com</middleware></p>
<p>これは<middleware>yahoo.co.jp</middleware></p>
@endsection
コントローラの修正
public function index(Request $request)
{
return view('hello.index');
}
今回はコントロー側では何もしていない。
では、/helloにアクセスして確かめる。