quimcalpe / router
基于正则表达式的路由器,易于使用,功能丰富
3.0.0
2023-04-26 13:47 UTC
Requires
- php: >=8.1
- psr/http-message: ^1.0
- symfony/http-foundation: ^6.2
Requires (Dev)
- phpunit/phpunit: ^9.6
- roave/security-advisories: dev-master
README
基于正则表达式的路由器,易于使用,功能丰富。它包括各种内置的调度器,我们还提供了一种接口来为您项目开发完全定制的调度器。
安装
通过Composer
$ composer require quimcalpe/router
要求
以下版本的PHP支持此版本。
- PHP 8.1
基本用法
// Require composer autoloader require __DIR__ . '/vendor/autoload.php'; use QuimCalpe\Router\Router; use QuimCalpe\Router\Dispatcher\SimpleDispatcher; // Create Router instance $router = new Router(); // Define routes, last parameter defining route name is optional $router->addRoute('GET', '/users', 'Quimi\Controllers\UserController', 'user_list'); $router->addRoute('GET', '/users/edit/{id:number}', 'Quimi\Controllers\UserController::edit', 'user_edit'); $router->addRoute(['POST', 'DELETE'], '/users/remove/{id:number}', 'Quimi\Controllers\UserController::remove', 'user_delete'); // Sugar methods for common verbs are also available (GET, POST, PUT, DELETE...) $router->addGet('/user/{id}', 'Quimi\Controllers\UserController::show', 'user_show'); // You can also create a QuimCalpe\Router\Route\Route value object and add directly to router's `->add()` $route = new Route('GET', '/', 'Quimi\Controllers\HomeController', 'home'); $router->add($route); try { // Match routes $route = $router->parse($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']); // Dispatch route $dispatcher = new SimpleDispatcher(); $response = $dispatcher->handle($route); } catch (QuimCalpe\Router\Exception\MethodNotAllowedException $e) { header('HTTP/1.0 405 Method Not Allowed'); // exception message contains allowed methods header('Allow: '.$e->getMessage()); } catch (QuimCalpe\Router\Exception\RouteNotFoundException $e) { header('HTTP/1.0 404 Not Found'); // not found.... }
构造函数可选 Route[] 参数
您可以选择将 Route 对象数组传递给 Router 的构造函数,并创建路由;
use QuimCalpe\Router\Router; use QuimCalpe\Router\Route\Route; $routes = [ new Route('GET', '/users', 'Quimi\Controllers\UserController', 'user_list'), new Route('GET', '/users/edit/{id:number}', 'Quimi\Controllers\UserController::edit', 'user_edit'), new Route(['POST', 'DELETE'], '/users/remove/{id:number}', 'Quimi\Controllers\UserController::remove', 'user_delete'), ] $router = new Router($routes);
此数组可以来自另一个文件,从而以简单的方式实现配置分离。
路由提供者
如果您想从特定的包/命名空间/捆绑包导入大量路由,并希望保持路由的有序性,您可以使用路由提供者,如下定义您的提供者
namespace My\Package; use QuimCalpe\Router\Route\Route; use QuimCalpe\Router\Route\RouteProvider; class MyPackageRoutes implements RouteProvider { public function routes(): array { return [ new Route('GET', '/users', 'Quimi\Controllers\UserController', 'user_list'), new Route('GET', '/users/edit/{id:number}', 'Quimi\Controllers\UserController::edit', 'user_edit'), new Route(['POST', 'DELETE'], '/users/remove/{id:number}', 'Quimi\Controllers\UserController::remove', 'user_delete'), ]; } }
然后使用以下方式初始化 Router
$router = new Router(); $router->addRouteProvider(new \My\Package\MyPackageRoutes());
路由模式
支持基本的正则表达式模式,其中一些已包含在内
[^/]+
作为默认值- 'word' =>
\w+
- 'number' =>
\d+
- 'slug' =>
[A-Za-z0-9_-]+
可以使用这种方式使用模式
$router->addRoute('GET', '/users/edit/{id:number}', 'Controller::action'); $router->addRoute('GET', '/users/{name:word}', 'Controller::action');
您可以定义自己的模式
$router->addPattern("phone", "[0-9]-[0-9]{3}-[[0-9]{3}-[0-9]{4}"); // #-###-###-#### $router->addRoute("GET", "/customer/{phone:phone}", "Vendor\Package\Controller"); $parsedRoute = $router->parse("GET", "/customer/1-222-333-4444");
通配符
路由中的通配符可以使用 WildcardDispatcher
来使用
$router->addRoute('GET', '/test/{controller}/{action}/{id}', 'Vendor\Package\{controller}::{action}'); $parsedRoute = $router->parse("GET", "/test/user/edit"); $dispatcher = new WildcardDispatcher; $response = $dispatcher->handle($parsedRoute); // => Vendor\Package\User::edit($id)
请求响应
支持使用 RequestResponseDispatcher
的标准请求-响应工作流程与 Symfony HttpFoundation 组件
use Symfony\Component\HttpFoundation\Request; use QuimCalpe\Router\Router; use QuimCalpe\Router\Dispatcher\RequestResponseDispatcher; $router = new Router(); $router->addRoute('GET', '/users', 'Quimi\Controllers\UserController::index'); $request = Request::createFromGlobals(); $route = $router->parse($request->getMethod(), $request->getPathInfo()); // You can optionally modify the request object here before dispatching: $request->attributes->set('foo', 'bar'); $dispatcher = new RequestResponseDispatcher($request); $response = $dispatcher->handle($route); $response->send();
PSR-7 HTTP 消息
内置的 PSR7Dispatcher
可用于与 PHP-FIG 的 PSR-7 HTTP 消息标准实现一起工作,例如使用 Zend Diactoros 和简单的 PSR-7 Response Sender 的示例如下
use QuimCalpe\Router\Router; use QuimCalpe\Router\Route\Route; use QuimCalpe\Router\Dispatcher\PSR7Dispatcher; use function QuimCalpe\ResponseSender\send AS send_response; use Zend\Diactoros\ServerRequestFactory; use Zend\Diactoros\Response; $router = new Router(); $router->add(new Route("GET", "/test", "ControllerFoo")); $request = ServerRequestFactory::fromGlobals(); $route = $router->parse($request->getMethod(), $request->getUri()->getPath()); $dispatcher = new PSR7Dispatcher($request, new Response()); $response = $dispatcher->handle($route); send_response($response);
自定义调度器
您可以创建自己的自定义调度器,实现 DispatcherInterface
interface DispatcherInterface { public function handle(ParsedRoute $route): mixed; }
QuimCalpe\Router\Route\ParsedRoute
是一个小的值对象,它具有由 Router::parse
解析的 controller()
和 params()
方法。
尾部斜杠
默认行为是区分带有和没有尾部斜杠的路由
$router = new Router(); $router->addRoute('GET', '/users', 'Controller'); $router->parse('GET', '/users'); // => OK! $router->parse('GET', '/users/'); // => NOT FOUND
您可以使用 disableTrailingSlashCheck
方法禁用此行为
$router = new Router(); $router->addRoute('GET', '/users', 'Controller'); $router->disableTrailingSlashCheck(); $router->parse('GET', '/users'); // => OK! $router->parse('GET', '/users/'); // => OK!
测试
$ vendor/bin/phpunit
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 以获取更多信息。