概要
会社のプロジェクトをcakephpの3.8から4.0に上げる際にMiddlewareの互換性について調べたのでメモ。
4.0でのMiddlewareの変更点
cakephp4からpsr-15の仕様をサポートするようになったためcakephpが提供しているMiddlewareはMiddlewareInterfaceを実装しています。
cakephp3で独自のMiddlewareを作成している場合は互換性が気になるところですが、ドキュメントに書いてある通り後方互換性が保たれているのでバージョンを4にするあたり何か既存のMidllewareを書き換えなくてはいけないということは基本はないはずです。(もちろん書き換えないといけない場合もあると思います。)
どの様に互換性を保っているのか
結論から言うとMiddlewareInterfaceを実装していないクラス(__invoke( )を実装してる)をDoublePassDecoratorMiddlewareクラスでラップしているだけです。
1 . DoublePassDecoratorMiddlewareクラスの__constructにMiddlewareを引数で渡して$callableプロパティに代入する( __invoke( )を実装しているインスタンスはcallable型です)
class DoublePassDecoratorMiddleware implements MiddlewareInterface
{
protected $callable;
public function __construct(callable $callable)
{
$this->callable = $callable;
}
}
2 . 最終的にDoublePassDecoratorMiddlewareクラスのprocessメソッドが呼ばれる。実態は$callableプロパティのMiddleware->__invoke( )が実行される。
class DoublePassDecoratorMiddleware implements MiddlewareInterface
{
protected $callable;
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
return ($this->callable)(
$request,
new Response(),
function ($request, $res) use ($handler) {
return $handler->handle($request);
}
);
}
}
(もっと詳しい流れが知りたい方は是非コードを読んでみてください)
補足
4.3.0からDoublePassDecoratorMiddlewareクラスは非推奨となっています。
(代わりにクロージャーかMiddlewareInterfaceを実装しよう!と書いてあります。)