artyuum / router
另一个PHP请求路由器。
Requires
- php: ^8.0
- symfony/http-foundation: ^4.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.2
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-09-21 00:59:36 UTC
README
注意:此路由器尚未完全功能化,仍在开发中。将很快发布一个稳定版本。
功能
- RESTful路由器。
- 附带Symfony Http Foundation。
- 支持命名路由参数和占位符。(正在进行中)
- 支持路由分组(以及嵌套分组)。
- 支持命名路由(带有反向路由)。(正在进行中)
- 支持路由前后中间件。
- 支持全局中间件的前后。
- 支持路由前缀。
- 支持路由映射。
- 支持自定义404处理器。
安装
composer require artyuum/router:dev-master
文档
注册路由
该路由器包含一些用于最常见HTTP方法的函数,可以帮助您轻松注册路由。
$router->get(string $uri, $handler); $router->post(string $uri, $handler); $router->put(string $uri, $handler); $router->patch(string $uri, $handler); $router->delete(string $uri, $handler); $router->options(string $uri, $handler);
这些只是以下方法的包装:
$router->addRoute(array $methods, string $uri, $handler);
使用addRoute()
方法,您可以注册一个匹配多个HTTP方法的路由。
$router->addRoute(['GET', 'POST'], string $uri, $handler);
路由器不会限制您的应用程序只使用最常用的HTTP方法。实际上,您还可以注册一个匹配自定义HTTP方法的路由。
$router->addRoute(['BLAH'], string $uri, $handler);
$handler
参数必须是可调用的或数组(如果是类的话)。
// using an anonymous function $router->get('/', function(\Symfony\Component\HttpFoundation\Request $request, \Symfony\Component\HttpFoundation\Response $response) { echo 'hello world'; }); // using a function name $router->get('/', 'myFunction'); // using an array (if it's a class) $router->get('/', [HomepageController::class, 'index']);
一旦请求与已注册的路由之一匹配,路由器将执行处理器,并按以下顺序传递两个参数:
-
Symfony\Component\HttpFoundation\Request $request
-
Symfony\Component\HttpFoundation\Response $response
这些参数是Symfony HTTP Foundation组件的一部分,并可以帮助您获取有关请求的更多信息,以及轻松构建并发送响应给客户端。您可以阅读文档以获取有关其使用的更多信息。
路由参数
可以使用占位符或纯正则表达式(PCRE)设置路由参数,如下所示:
$router->get('/profile/{username}', $handler); // will be internally converted to /profile/?<username>(\w+)
当使用纯正则表达式时,重要的是要给分组命名(如上所示)。否则,路由器将无法从URL中获取参数,它也无法使用url()
方法正确地构建指向路由的URL。
默认情况下,占位符将被转换为匹配至少一个字母、数字或_的必选参数。您可以通过使用where()
方法来更改此行为,如下所示:
$router->get('/profile/{id}', $handler)->where([ 'id' => '[0-9]+' // can also be written as "\d+" ]); // will match /profile/<one or n digit(s) from 0 to 9>
where(array $placeholders)
方法接受一个关联数组作为参数,其中$key
是占位符的名称,$value
是正则表达式。
您还可以通过在占位符名称后附加一个"?"符号来将占位符设置为可选,如下所示:
$router->get('/profile/{username?}', $handler); // will match /profile OR /profile/<any word of at least one letter, number or _>
命名路由
命名路由允许您通过名称轻松找到已注册的Route对象。使用返回的对象,您将能够访问此对象的所有方法(例如getPath()
、getName()
、getMiddlewares()
、getHandler()
等...)
示例
// registers a route named "homepage" $router->get('/', $handler)->setName('homepage'); // registers a route named "user.delete" $router->get('/users/{id}/delete', $handler)->setName('user.delete'); // gets the Route instance of the "homepage" route $route = $route->getRoute('homepage'); // builds an url to a route $url = $router->url('homepage'); // /home // builds an url to a route with parameters $url = $router->url('user.delete', ['id' => 1]); // /users/1/delete
路由分组
您可以使用group()
方法对路由进行分组。这使得您能够为组内的所有路由设置前缀或中间件。
路由URI前缀
示例
// homepage $router->get('/', $handler); // will match "/" // admin $router->group(function(\Artyum\Router\RouteGroup $group) use ($router) { $group->setPathPrefix('/admin'); $router->get('/', $handler); // will match "/admin" });
路由名称前缀
示例
// homepage $router->get('/', $handler); // will match "/" // admin $router->group(function(\Artyum\Router\RouteGroup $group) use ($router) { $group->setNamePrefix('admin.'); $router->get(string $uri, $handler)->setName('homepage'); // name will be "admin.homepage" });
路由中间件
示例
$router->group(function(\Artyum\Router\RouteGroup $group) use ($router) { $group->addMiddlewares([ 'before' => [RateLimitMiddleware::class, AuthMiddleware::class], 'after' => [LoggingMiddleware::class] ]); $router->get(string $uri, $handler); $router->post(string $uri, $handler); });
如果请求与已注册的某个路由匹配,则路由器将按以下顺序执行以下操作
- 首先,执行
RateLimitMiddleware
类的handle()
方法。 - 其次,执行
AuthMiddleware
类的handle()
方法。 - 第三,执行匹配的路由控制器。
- 最后,执行
LoggingMiddleware
类的handle()
方法。
路由器将自动执行中间件类的handle()
方法,因此您不需要指定它。
您还可以将路由前/后中间件添加到组中,如下所示
$router->group(function(\Artyum\Router\RouteGroup $group) use ($router) { $group->setBeforeMiddlewares([RateLimitMiddleware::class, AuthMiddleware::class]); $group->setAfterMiddlewares([LoggingMiddleware::class]); });
这些仅仅是围绕addMiddlewares()
方法的包装器。
路由映射
您可以将单个URI映射到多个不同的HTTP方法和不同的处理器,如下所示
$router->map('/users/{id}') ->put($handler) ->patch($handler) ->delete($handler);
使用withAttributes()
方法,您将能够访问路由对象,以便为路由设置额外的属性
$router->map('/users/{id}') ->put($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route ->setName('user.replace') ->setBeforeMiddlewares([RateLimitMiddleware::class, RolesMiddleware::class]); }) ->patch($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route ->setName('user.update') ->setBeforeMiddlewares([RateLimitMiddleware::class, RolesMiddleware::class]); }) ->delete($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route ->setName('user.delete') ->setBeforeMiddlewares([RateLimitMiddleware::class, RolesMiddleware::class]); });
还可以将映射的路由添加到组中,这样您就可以为组内的所有路由设置中间件,并且还可以设置名称前缀
$router->group(function(\Artyum\Router\RouteGroup $group) use ($router) { $group->setBeforeMiddlewares([RateLimitMiddleware::class, RolesMiddleware::class]); $group->setNamePrefix('user.'); $router->map('/users/{id}') ->put($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route->setName('replace'); }) ->patch($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route->setName('update'); }) ->delete($handler)->withAttributes(function(\Artyum\Router\Route $route) { $route->setName('delete'); }); });
路由未找到
默认情况下,当请求不匹配任何已注册的路由时,dispatch()
方法将抛出“NotFoundException”。您可以通过注册处理器来更改此行为。注册的处理器将与控制器或中间件相同的参数执行。
setNotFoundHandler($handler);
示例
// sends a 404 status code if no routes match the current request $router->setNotFoundHandler(function(\Symfony\Component\HttpFoundation\Request $request, \Symfony\Component\HttpFoundation\Response $response) { $response ->setStatusCode(404) ->send(); });
贡献
如果您想做出贡献,请fork仓库并根据您的意愿进行更改。我们热情地欢迎拉取请求。