[PHP]Slim3のnikic/FastRouteパッケージで、Controller-Actionスタイルのルーティングを行う

カテゴリ: FastRoute, SlimFramework | タグ:

PHPでルーティングを行うパッケージであるnikic/FastRouteパッケージを利用して、controller-actionスタイルのルーティングを行う方法を説明します。

nikic/FastRouteパッケージは、PHP本体の開発者であるNikitaさんが開発していて、Slim3 Frameworkでも採用されているシンプルで高速なルーティングパッケージです。

controller-actionスタイルって何?

controller-actionスタイルというのは、左のようなURLが来た時に、URLからクラス名とメソッド名を特定し、矢印の右側にあるメソッドを読んでくれるようなルーティングを行う方法です。

http://example.com/user/list   -> UserController::list()
http://example.com/user/index  -> UserController::index()
http://example.com/user/       -> UserController::index()

上に書かれたUserControllerクラスは、以下のような普通のPHPクラスです。今回の例では、App\Controllerネームスペースをつけています。

namespace App\Controller;

class UserController
{
    public function index(Request $request, Response $response, $args) {
        return "index called";
    }

    public function list() {
        return "list called";
    }
}

controller-actionタイプのルーティング処理

今回行いたいルーティングのルールは、ホスト名の後に来る1つ目の要素がコントローラ名(クラス名を特定するもの)で、2つ目がアクション名(メソッド名)とみなします。また、アクション名を省略した場合はindexが指定されたとみなします。

この要件を満たすルーティング処理は以下のようになります。

<?php
include "UserController.php";

$app->get('/{controller}[/{action}]', function (Request $request, Response $response, array $args) {
    $prefix = '\\App\\Controller\\';
    $suffix = 'Controller';

    // アクションを実行するクラス、メソッド名を取得
    // action名省略時はindexとみなす
    $controllerName = $prefix . $args['controller'] . $suffix;
    $methodName = $args['action'] ?? 'index';

    // 指定されたアクションを実行
    $c = new $controllerName;
    $response = $c->$methodName($request, $response, $args);

    return $response;
});

$app->get()の第二引数で指定しているクロージャーでこのルーティングを行っています。先ほど提示した例ではURLでhttp://example.com/user/が指定されたときに、App\Controller\UserControllerのクラスを使用していました。

Urlで指定された名称"user"の前に、接頭語としてApp\Controller\、また接尾語としてControllerをつける必要があるため、この文字列をprefix/suffixの変数で管理しています。

また、メソッド名は以下のように省略時は、indexが指定されたとみなしています。

$methodName = $args['action'] ?? 'index';

この処理は、PHP 5.Xなど古いバージョンのPHP環境で??演算子が使えない場合は、以下のように書き換える必要があります。

$methodName = !isset($args['action']) ? $args['action'] : 'index';

クラス名とメソッド名が決定したら、名称を元に動的にクラス生成・メソッド呼び出しを行えばよいです。

// 指定されたアクションを実行
$c = new $controllerName;
$response = $c->$methodName($request, $response, $args);

これで、最初に提示したようなcontroller-actionスタイルのルーティングが行えるようになります。

こちらもおススメ

コメントを残す

メールアドレスが公開されることはありません。