ngyuki/route-collector

简单的路由收集器

v0.0.1 2018-01-15 10:35 UTC

This package is auto-updated.

Last update: 2024-09-22 15:05:44 UTC


README

Build Status Coverage Status Latest Stable Version Latest Unstable Version License

我想创建一个可以通过方法链定义路由定义的示例。

示例

$registry = new RouteRegistry();
$r = new RouteCollector($registry);

// GET / -> HomeController::index
$r->path('/')->get()->controller('HomeController')->action('index');

// GET|POST /both -> HomeController::both
$r->path('/both')->get()->post()->controller('HomeController')->action('both');

// GET|POST /both -> HomeController::method
$r->path('/method')->method('GET|POST')->controller('HomeController')->action('method');

$r->controller('UserController')->group(function (RouteCollector $r) {
    $r->path('/user')->group(function (RouteCollector $r) {

        // GET /user -> UserController::index
        $r->get()->action('index');

        // GET /user/create -> UserController::create
        $r->path('/create')->get()->action('create');

        // POST /user/create -> UserController::store
        $r->path('/create')->post()->action('store');
    });
    $r->path('/user/{id}')->group(function (RouteCollector $r) {

        // GET /user/{id} -> UserController::show
        $r->get()->action('show');

        // GET /user/{id}/edit -> UserController::edit
        $r->path('/edit')->get()->action('edit');

        // PUT /user/{id}/edit -> UserController::update
        $r->path('/edit')->put()->action('update');

        // DELETE /user/{id}/edit -> UserController::delete
        $r->path('/edit')->delete()->action('delete');
    });
});

return $registry->getRoutes();

详细说明

这是一个使用方法链从内部 DSL 创建路由定义数组的库。

以下方法用于定义路由。

  • path(string $path)
    • URL 的请求路径
  • get()/post()/put()/patch()/delete()/method(string $method)
    • 请求方法
  • params(array $params)
  • param(string $name, mixed $value)
    • 路由参数

使用除这些名称之外的其他名称调用魔法方法时,将被替换为 param($name, $value)。因此,以下两种调用是等效的。

$r->controller('HomeController')->action('index');
$r->param('controller', 'HomeController')->param('action', 'index');

在链中断处注册一个路由。

// これで1つのルート定義
$r->path('/')->get()->controller('HomeController')->action('index');

交换链的顺序也不会影响结果。

// ↑と同じルート定義
$r->action('index')->controller('HomeController')->get()->path('/');

将多个请求方法链连起来可以匹配多个请求方法。

// GET と POST の両方にマッチします
$r->path('/')->get()->post()->controller('HomeController')->action('index');

请求方法可以通过 method() 使用字符串字面量或管道符号进行指定。

// GET と POST の両方にマッチします
$r->path('/')->method('GET|POST')->controller('HomeController')->action('index');

path 的链连起来可以连接路径。

// '/aaa/bbb' にマッチします
$r->path('/aaa')->path('/bbb')->get()->controller('HomeController')->action('index');

params 的链连起来是合并的。

// params(['aaa' => 9, 'bbb' => 2, 'ccc' => 3]) とマージされる
$r->path('/')->get()
    ->params(['aaa' => 1])
    ->params(['aaa' => 9, 'bbb' => 2])
    ->params(['ccc' => 3]);

使用 group 可以基于部分定义的路由定义创建多个路由定义。

可以在链的中间定义多个路由。

$r->controller('UserController')->group(function (RouteCollector $r) {
    // このブロックのルート定義ではコントローラーに UserController が適用される

    $r->get()->path('/users')->action('index');
    $r->post()->path('/users')->action('store');

    $r->path('/user/{id}')->group(function (RouteCollector $r) {
        // このブロックのルート定義ではパスの先頭に /user/{id} が追加される

        // /user/{id}
        $r->get()->action('show');

        // /user/{id}/edit
        $r->get()->path('/edit')->action('edit');
    });
});

抑制魔法方法的警告

使用魔法方法时,PhpStorm 会显示警告,但如果你在继承自 RouteCollector 的类中添加 @method 注解,则不会有问题。

// MyRouteCollector.php

/**
 * @method $this controller(string $controller)
 * @method $this action(string $action)
 */
class MyRouteCollector extends RouteCollector {}
// routes.php

$registry = new RouteRegistry();
$r = new MyRouteCollector($registry);

本来应该使用 static 而不是 $this,但不知为何,在 PhpStorm 中使用 @method 时,无法启用 static 的补全,因此使用了 $this

如果你介意的话,请不要使用 @method,而是直接定义方法。这样,即使在 static 中也可以进行补全。

// MyRouteCollector.php

class ActionRouteCollector extends RouteCollector
{
    /**
     * @param string $controller
     * @return static
     */
    public function controller($controller)
    {
        return $this->param(__FUNCTION__, $controller);
    }
}