はじめに
フレームワークのミドルウェアを深く理解したくて、PHPで簡単なミドルウェアチェーンのコードを通して、処理の流れをイメージできるようにした。
今回はその中で学んだポイントを整理する。
PHPのアロー関数(fn)は無名関数の短縮形であり、use
を省略できる
$fn1 = fn($x) => $x + $y;
$fn2 = function($x) use ($y) { return $x + $y; };
このように、アロー関数では外部変数を明示的に use
しなくても、スコープ内にある変数は自動でクロージャとして取り込まれる。
前処理を a → b → c、後処理を c → b → a の順で行いたい場合、c → b → a の順で関数を包めばよい
以下のような Middleware
インターフェースを実装した複数のクラス(A, B, C)があるとする。
interface Middleware {
public function handle(string $request, callable $next): string;
}
それぞれの handle
メソッドで、前後処理を実装する。
class MiddlewareA implements Middleware {
public function handle(string $request, callable $next): string {
$request .= "[A:before]";
$response = $next($request);
return $response . "[A:after]";
}
}
ミドルウェアは配列で保持しておき、入れ子構造を逆順に構築する。
$middlewares = [new MiddlewareA(), new MiddlewareB(), new MiddlewareC()];
$middlewares = array_reverse($middlewares);
$action = fn(string $request): string => $request;
foreach ($middlewares as $middleware) {
$action = fn(string $request) => $middleware->handle($request, $action);
}
この時点で $action
は、以下のような構造になる。
A(
B(
C(
BaseAction
)
)
)
つまり、
- 実行時:A → B → C → Base
- 戻り時:C → B → A(後処理)
という流れが実現される。
まとめ
- アロー関数は
use
を省略できる。 - ミドルウェアで「ある処理の前後に共通の処理を挟みたい」とき、ラップ構造で実現できる
- 実行順と戻り順をコントロールしたいなら、「wrapの順番」を逆に考えること
おわりに
今回の学びを通して、ミドルウェアが「ベースの処理を引数として受け取るメソッド」であることが腑に落ちた。