【CakePHP】RouteBuilderのprefixで詰まったこと

こんにちは、しましまです。
今回は最近のコーディングで詰まった RouteBuilder の prefix についてまとめます。

詰まった内容

今回詰まったのは、リクエストの中にあるprefix を用いて、クラスの名前空間を指定する箇所でした。
以下は実際のコードとなります。

routes.php

return function (RouteBuilder $routes): void {
  $routes->prefix('Admin', static function (RouteBuilder $routes): void {
    $routes->prefix('User', static function (RouteBuilder $routes): void {
        // 省略
    }
  }
}

Middleware.php

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $params = $request->getAttribute('params')
        $prefix = $params['prefix'] ?? null;
        // 名前空間でクラス指定(省略)
    }

上記の場合、Admin/User 配下にアクセスすると、Middleware.php の $prefix には Admin/User が入っています。
なにが問題かというと、のちのソースでこの $prefix を用いてコントローラの名前空間を指定するのですが、
名前空間はバックスラッシュで区切る必要があるため、スラッシュのままだとコントローラが見つからないという結果となりました。

今回は、$prefix 内のスラッシュをバックスラッシュに置換する処理を追加することで対応しましたが、いくつか試したところ、route.php の書き方を変更する方法があることも確認しました。

return function (RouteBuilder $routes): void {
  $routes->prefix('Admin', static function (RouteBuilder $routes): void {
    $routes->prefix('User', static function (RouteBuilder $routes): void {
        $routes->scope(... , static function (RouteBuilder $routes): void {
                // connect を用いてprefixを修正
                $routes->connect('/{action}', ['prefix' => 'Admin\User'])
                    ->setMethods(['POST']);
            });
    }
  }
}

上記のようにconnectメソッドを用いてprefixを修正することもできました。

ただ、route.php に記述すると他のルーティング設定にも追加する必要があり、冗長なものとなってしまうため、今回は実際に使う箇所で置換する方針となりました。