のぐそんブログ

暗いおじさんがシコシコ書くブログです。

Laravelでのミドルウェアメモ

ミドルウェアとは

リクエストがコントローラーのアクションに届く前後に処理をさせることができます。 指定のアドレスにリクエストが送られてきたら、自動的に何らかの処理を行う機能です。

ミドルウェアを作成する

ミドルウェアは以下のコマンドで作成できる。

php artisan make:middleware MyMiddleware

作成したファイルはapp/Http/Middlewareに作成されます。

<?php

namespace App\Http\Middleware;

use Closure;

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

使い方

リクエストで送られてきた値の$requestミドルウェアで値を追加します。

◎app/Http/Middleware/MyMiddleware.php

class MyMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $data = [
            ['name' => '佐藤', 'age' => 30],
            ['name' => '伊藤', 'age' => 40]
        ];

        $request->merge(['data'=>$data]);
        return $next($request);
    }
}

ミドルウェアルートで呼び出します。

追加の仕方は、以下のようにメソッドチェーンとして設定することができます。

Route::get(...)->middleware()->middleware();

◎routes/web.php

Route::get('hello/', 'HelloController@index')
    -> middleware(HelloMiddleware::class);

コントローラーでミドルウェアで追加した値を取得します。

◎app/Http/Controllers/MyController.php

class MyController extends Controller
{
    public function index(Request $request)
    {
        return view('index', ['data'=>$request->data]);
    }
}

Viewでミドルウェアで追加した値を表示します。

◎resources/views/index.blade.php

@foreach($data as $item)
    <span>{{$item['name']}}</span>
    <span>{{$item['age']}}</span>
@endforeach

表示

佐藤 30 伊藤 40

前処理と後処理

$next(response)の使い方で実行タイミングを制御することができます。

コントローラーの実行前の場合は

public function handle($request, Closure $next)
{
  /*
   * ここに処理を実装する
   */

  return $next($request);
}

コントローラー実行後の場合は

public function handle($request, Closure $next)
{
  $response = $next($request);

  /*
   * ここに処理を実装する
   */

  return $response;
}

後処理を試してみる

<hoge>タグを<a>タグに置き換える処理をミドルウェアの後処理で行ってみます。

◎app/Http/Middleware/MyMiddleware.php

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

        // レスポンスに含まれるhtmlテキストを取得
        $content = $response->content();
            
        $pattern = '/<hoge>(.*)<\/hoge>/i';
        $replace = '<a href="$1">$1</a>';
        
        // テキストを置き換え
        $content = preg_replace( $pattern,$replace,$content);

        $response->setContent($content);
        return $response;
    }
}

◎resources/views/index.blade.php

<hoge>http://google.com</hoge>

◎app/Http/Controllers/MyController.php

class MyController extends Controller
{
    public function index(Request $request)
    {
        return view('index');
    }
}

表示

http://google.com

全てのアクセスでミドルウェアを実行してみる

全てのアクセスでミドルウェアを実行する場合は、app/Http/Kernel.phpに設定を追加します。 ここに登録することで、routeなどでミドルウェアを個別に指定する必要はなくなります。

    protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        ... 省略 ...
        // ここに追加
    ];

ミドルウェアのグループ化

複数のミドルウェアをまとめて定義することもできます。 app/Http/Kernel.phpの以下の箇所に追加します。

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            ... 中略 ...
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
        // 追加する
        'hoge' => [
            \App\Http\Middleware\HelloMiddleware::class,
            //ミドルウェアを追加する
        ]
    ];

設定したミドルウェアグループをrouteで呼び出します。

◎routes/web.php

Route::get('hello/', 'HelloController@index')
    -> middleware('hoge');