ifcanduela/router

封装FastRoute的路由组件

1.1.0 2021-09-15 13:10 UTC

This package is auto-updated.

Last update: 2024-09-15 19:39:50 UTC


README

PHP路由封装nikic/fast-route,支持嵌套路由组、默认参数以及其他一些额外功能。

安装

使用Composer

composer require ifcanduela/router

使用方法

创建一个ifcanduela\router\Router实例并定义路由

$router = new ifcanduela\router\Router();
$router->get("/")->to("my_controller");

从文件中加载路由

从文件中加载路由是初始化路由的首选方法。例如,创建一个名为routes.php的文件

<?php

/** @var ifcanduela\router\Router $r */

$r->get("/")->to("home");

$r->group("/admin", function (ifcanduela\router\Group $g) {
    $g->get("/dashboard")->to("admin@dashboard");
});

// `$this` can also be used

$this->post("/save")->to("admin@save");

然后这样加载文件

$router = new ifcanduela\router\Router();
$router->loadFile("routes.php", "r");

loadRoute()的第二个参数定义了加载文件中路由器的名称;默认为router。此外,$this元变量总是在加载的文件中可用,它指向调用Group或Router。

文件也可以从嵌套组中加载

$router->group("/admin", function (ifcanduela\router\Group $g) {
    $g->loadFile("admin-routes.php");

    $g->group("/settings", function (ifcanduela\router\Group $g) {
        $g->loadFile("admin-settings-routes.php");
    });
});

路由定义

路由主要使用Router或Group方法创建

$group = new Group();
$group->from("/home")->to("home_controller");
$group->get("/login")->to("login_form");
$group->post("/login")->to("login_submit");

在幕后,这些方法调用Route类中的静态构造函数

$group = new Group();
$group->routes([
    Route::from("/home")->to("home_controller"),
    Route::get("/login")->to("login_form"),
    Route::post("/login")->to("login_submit"),
]);

getpostputdelete方法创建只匹配具有相同HTTP方法的请求的路由。默认情况下,from方法允许GETPOST,但Group::from方法接受更多字符串参数,允许更多的HTTP方法。

此外,还可以在路由上调用methods方法来覆盖其允许的方法

Route::from("/update-user/{id}", "get", "post")->to("api@updateUser");
Route::from("/create-user")->to("api@createUser")->methods(["PATCH"]);

路由遵循nikic/fast-route定义的语法,因此可以使用花括号添加参数,并使用方括号将段包裹起来以使其可选。还可以为可选参数添加默认值

Route::from("/projects/{id}[/{version}]")
    ->to("project_dashboard")
    ->default("version", "latest");

路由组

当多个路由共享前缀或元数据时,可以将它们放在一个组中。定义组的方法有多种,但它们的效果是相同的。首先,将组视为路由器的一种通用方式

$adminGroup = $router->group();
$adminGroup->prefix("/admin");
$adminGroup->get("/dashboard")->to([AdminController::class, "dashboard"]);
$adminGroup->get("/users")->to([UsersController::class, "index"]);

一种更清晰的方法是使用回调来定义分组路由

$router->group("/admin", function ($adminGroup) {
    $adminGroup->prefix("/admin");
    $adminGroup->get("/dashboard")->to([AdminController::class, "dashboard"]);
    $adminGroup->get("/users")->to([UsersController::class, "index"]);
});

解析路由

路由器需要一个路径和一个HTTP方法来解析路由。如果没有找到匹配的路由,则会抛出异常。

$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
$pathInfo = $request->getPathInfo();
$method = $request->getMethod();

try {
    $route = $router->resolve($pathInfo, $method);
} catch (\ifcanduela\router\InvalidHttpMethod $e) {

} catch (\ifcanduela\router\RouteNotFound $e) {

}

路由元数据

可以将额外的信息附加到路由上,以更好地识别它们并促进其在请求/响应周期中的使用。

路由名称

路由可以通过名称来识别,这有助于在创建指向它们的URL时使用

$router->get("/example/view/{id}")->to("example@view")->name("example.view");

$url = $router->createUrlFromRoute("example.view", [123]);
//=> "/example/view/123"

您可以使用路径和方法组合来检查是否与路由名称匹配

$pathInfo = $request->getPathInfo();
$method = $request->getMethod();

$router->isRoute("example.view", $pathInfo, $method);
//=> true/false

标记路由(之前/之后)

标记路由对于在匹配路由之前或之后运行中间件非常有用。

Route::from("/path")->to("handler")
    ->before(MyMiddleware::class, "some_other_thing");

标记路由的另一种方式是使用命名空间

Route::from("/admin/index")->to("admin_index")
    ->namespace("admin");

如果您正在为中间件使用标签,则可以将全局中间件(应用于所有路由)附加到路由器本身

$router->before(StartSession::class);
$router->after(ConvertToResponse::class, SendResponse::class);

一旦路由被解析,就可以使用$route->getBefore()$route->getAfter()访问所有适用的标签。

许可证

MIT.