Laravelのミドルウェア【個人的なお勉強アウトプット】

# 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

WEBの基本は、アクセスしてリクエストを受け取り、結果をレスポンスを返す。
その基本となる部分を補完する様々な機能がLaravelには用意されている。

## ミドルウェアとは
コントローラとは別に、「指定のアドレスにリクエストが送られてきたら、自動的に何らかの処理を行う」という仕組み。
リクエストに対して共通する処理はコントローラに置くと重複するし、重くなる。そのような処理はミドルウェアで処理させる。
ミドルウェアはリクエストがコントローラのアクションに届く前（または後）に配置されるレイヤー層のプログラム。
ミドルウェアの設定はルート情報を記述する際に指定する。
コントローラとは完全に分離されているため、コントローラの処理には左右されない。

### リクエスト、レスポンスの流れにミドルウェアがどう絡むか
①リクエストが送られる
②ミドルウェアのhandleが呼び出される。
③ミドルウェアで`$next`を実行する。複数ミドルウェアがある場合は次のミドルウェアのhandleが呼び出される
④他にミドルウェアがない場合はコントローラのアクションが呼び出される。
⑤アクションメソッドが終わるとレンダリングされ、レスポンスが生成される。生成されたレスポンスが`$next`の戻り値としてミドルウェアに返される。
⑥ミドルウェアで返送されたレスポンスがreturnとして返され、これがクライアントへ返送される。

上記の流れがあるのでミドルウェアはコントローラーのアクションの前と後で処理をはさみこめる。

## ミドルウェアの作成
`php artisan make:middleware HelloMiddleware`
app/Http/Middlewareにミドルウェアファイルが作成される
上述のHelloMiddlewareがファイル名。

### ミドルウェアファイル
```app/Http/Middleware/helloMiddleware.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class HelloMiddleware
{

    public function handle(Request $request, Closure $next)
    {
       return $next($request);
    }
}

```
第一引数の`$request`は、リクエストの情報を管理するRequestインスタンスが渡される。
`$next`はCloosureクラスのインスタンス。無名クラスを表すためのクラス。`$next`を呼び出し実行することで、ミドルウェアからアプリケーションを送るリクエスト（Requestインスタンス）を作成している。

### 前処理
```app/Http/Middleware/hogeMiddleware.php
public function handle($request, Closure $next){
//処理を実行する
return $next($request)
}
```
`$next`は上述の通り、無名関数のインスタンスが入った変数。
returnすることで、処理結果をコントローラに渡す。

### 後処理
```app/Http/Middleware/hogeMiddleware.php
public function handle($request, Closure $next){
$response = $next($request)
//処理を実行する
return $response;
}
```

`$response = $next($request)`でコントローラーでの処理結果（処理してなくても）を受け取っている。

## 前処理の実例
```app/Http/Middleware/helloMiddleware.php
class HelloMiddleware{
public function handle($request, Closure $next){
$data = [
['name'=>'taro', 'mail'=>'taro@web'],
['name'=>'hanako', 'mail'=>'hanako@web'],
['name'=>'sachiko', 'mail'=> 'sachiko@web'],
];
$request->merge(['data'=>$data]);
return $next($request);
}
}
```
mergeはフォームの送信で送られるinputの値に新たな値を追加するもの。
これによりdataという項目で`$data`の内容が追加される。
コントローラ側では$request->dataでこの値を取り出せる。

### ミドルウェアの実行
ルーティングでミドルウェアを呼び出す処理を記述する。
```routes/web.php
use App\Http\Middleware\HelloMiddleware;

Route::get('hello', 'App\Http\Controllers\HelloController@index')->middleware(HelloMiddleware::class);
```
Route::getの後にメソッドチェーンをつかってmiddlewareメドッドを追加する。
複数のミドルウェアを利用したい場合は`Route::get(...)->middleware(...)->middleware(...)`
と記述。

#### コントローラーでリクエストした値をビューに渡す
```app/Http/Controllers/HelloController.php
public function index(Request $request){
return view('hello.index', ['data'=>$request->data])
}
```
$requestをdataに置き換える。連想配列のdataというキー名にすることでビューに渡している。
ビューではdataという変数名で値を表示できる。

## 後処理の実例
```app/Http/Middleware/helloMiddleware.php
    public function handle(Request $request, Closure $next)
    {
       //最初に$nextを実行し、結果を$responseに代入
       //コントローラのアクションが実行され、結果のレスポンスが$responseに代入される。
       $response = $next($request);

       //$responseのcontentメソッドで、レスポンスに設定されているHTMLのソースコードのテキストを取り出せる。
       $content = $response->content();

       $content = '代入テキスト';

　　　　　　　　　　　　　　//レスポンスへのコンテンツの設定
       $response->setContent($content);
       return $response;
    }
}
```