divineniiquaye / flight-routing
Flight routing 是一个简单、快速且易于与其他路由器集成的 PHP 路由器。
Requires
- php: ^8.0
- laminas/laminas-stratigility: ^3.2
- psr/http-factory: ^1.0
- symfony/polyfill-php81: ^1.23
Requires (Dev)
- biurad/annotations: ^1.0
- divineniiquaye/php-invoker: ^0.9
- doctrine/annotations: ^1.11
- nyholm/psr7: ^1.4
- nyholm/psr7-server: ^1.0
- pestphp/pest: ^1.21
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^9.5
- spiral/attributes: ^2.9
- squizlabs/php_codesniffer: ^3.6
- vimeo/psalm: ^4.23
Suggests
- biurad/annotations: For annotation routing on classes and methods using Annotation/Listener class
- biurad/di: For full support of PSR-11 and autowiring capabilities on routes (recommended for install).
- biurad/http-galaxy: For handling router, an alternative is nyholm/psr7, slim/psr7 or laminas/laminas-diactoros
- divineniiquaye/php-invoker: For auto-configuring route handler parameters as needed with or without PSR-11 support
- laminas/laminas-httphandlerrunner: For emitting response headers and body contents to browser
- dev-master / 2.x-dev
- v2.1.0
- v2.0.11
- v2.0.10
- v2.0.2
- v2.0.1
- v2.0.0
- v1.6.4
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.1
- v1.5.0
- v1.4.1
- v1.4.0
- v1.0.0
- 0.5.x-dev
- v0.5.2
- v0.5.1
- v0.5.0
- v0.2.9
- v0.2.8
- v0.2.7
- v0.2.5
- v0.2.4
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.1
- v0.1.0
- v0.1-beta
- dev-dependabot/composer/vimeo/psalm-tw-5.8
- dev-dependabot/composer/doctrine/annotations-tw-2.0
- dev-perf-fix
This package is auto-updated.
Last update: 2024-09-10 22:17:57 UTC
README
PHP HTTP 路由
Flight routing 是为 PHP 提供的高性能 HTTP 路由器。它简单易用、可扩展且快速。此库依赖于 PSR-7 进行路由匹配,并支持使用 PSR-15 在渲染之前拦截路由。
此库的早期版本受到了 Sunrise Http Router、Symfony Routing、FastRoute 的启发,现在已完全重写以提高性能。
🏆 特性
- 支持所有 HTTP 请求方法(例如
GET
、POST
、DELETE
等)。 - 参数的正则表达式约束。
- 将命名路由路径反转到完整 URL,并带有严格的参数检查。
- 路由分组和合并。
- 支持路由缓存以提高性能。
- PSR-15 中间件(拦截路由渲染之前的类)。
- 域名和子域名路由。
- RESTful 路由。
- 支持 PHP 8 属性
#[Route]
和 doctrine 注解@Route
路由。 - 支持使用自定义路由匹配器类或编译器类使用自定义匹配策略。
📦 安装
此项目需要 PHP 8.0 或更高版本。推荐使用 Composer 进行安装。只需运行
$ composer require divineniiquaye/flight-routing
建议阅读我的博客文章设置 Apache、Nginx、IIS 服务器配置,以适应您的 PHP 项目。
📍 快速入门
默认编译器接受以下约束在路由模式中
{name}
- 必需占位符。{name=foo}
- 带有默认值的占位符。{name:regex}
- 带有正则定义的占位符。{name:regex=foo}
- 带有正则定义和默认值的占位符。[{name}]
- 可选占位符。
占位符变量的名称仅是可接受的 PHP 函数/方法参数名称,预期是唯一的,而正则定义和默认值可以是任何字符串(即 [^/]+)。
/foo/
- 匹配 /foo/ 或 /foo。匹配之前删除尾随斜杠。/user/{id}
- 匹配 /user/bob、/user/1234 或 /user/23/。/user/{id:[^/]+}
- 与前面的示例相同。/user[/{id}]
- 与前面的示例相同,但也可以匹配 /user 或 /user/。/user[/{id}]/
- 与前面的示例相同,匹配之前删除尾随斜杠。/user/{id:[0-9a-fA-F]{1,8}}
- 只有当 id 参数由 1 到 8 个十六进制数字组成时才匹配。/files/{path:.*}
- 匹配以 /files/ 开头的任何URL,并将路径的其余部分捕获到参数 path 中。/[{lang:[a-z]{2}}[-{sublang}]/]{name}[/page-{page=0}]
- 匹配 /cs/hello、/en-us/hello、/hello、/hello/page-12 或 /ru/hello/page-23。
路由模式接受以 //domain.com
或 https://domain.com
开头。路由路径还支持在路由路径的末尾直接添加控制器(即 *<controller@handler>
)。
*<App\Controller\BlogController@indexAction>
- 翻译为 BlogController 类的 indexAction 方法的可调用对象。*<phpinfo>
- 翻译为一个函数,如果路由中定义了处理器类,则它变为可调用对象。
以下是如何使用此库的示例。
use Flight\Routing\{Router, RouteCollection}; $router = new Router(); $router->setCollection(static function (RouteCollection $routes) { $routes->add('/blog/[{slug}]', handler: [BlogController::class, 'indexAction'])->bind('blog_show'); //... You can add more routes here. });
如果您更喜欢在闭包作用域外声明路由,请尝试以下示例。
use Flight\Routing\{Router, RouteCollection}; $routes = new RouteCollection(); $routes->get('/blog/{slug}*<indexAction>', handler: BlogController::class)->bind('blog_show'); $router = Router::withCollection($routes);
注意:如果启用了缓存,使用路由器的
setCollection()
方法比使用withCollection()
方法具有更高的性能。
默认情况下,Flight 路由不提供 PSR-7 HTTP 库或发送响应头和体到浏览器的库。如果您想安装这些库,我建议安装 biurad/http-galaxy 或 nyholm/psr7 和 laminas/laminas-httphandlerrunner。
$request = ... // A PSR-7 server request initialized from global request // Routing can match routes with incoming request $route = $router->matchRequest($request); // Should return an array, if request is made on a a configured route path (i.e /blog/lorem-ipsum) // Routing can also generate URLs for a given route $url = $router->generateUri('blog_show', ['slug' => 'my-blog-post']); // $url = '/blog/my-blog-post' if stringified else return a GeneratedUri class object
在下面的示例中,我假设您已安装了 nyholm/psr7 和 laminas/laminas-httphandlerrunner,因此我们可以使用 PSR-15 来拦截路由并在匹配之前,使用 PSR-17 将路由响应渲染到浏览器。
use Flight\Routing\Handlers\RouteHandler; use Laminas\HttpHandlerRunner\Emitter\SapiStreamEmitter; $router->pipe(...); # Add PSR-15 middlewares ... $handlerResolver = ... // You can add your own route handler resolver else default is null $responseFactory = ... // Add PSR-17 response factory $request = ... // A PSR-7 server request initialized from global request // Default route handler, a custom request route handler can be used also. $handler = new RouteHandler($responseFactory, $handlerResolver); // Match routes with incoming request and return a response $response = $router->process($request, $handler); // Send response to the browser ... (new SapiStreamEmitter())->emit($response);
要使用 PHP 8 属性支持,我强烈建议安装 biurad/annotations,如果您出于某种原因决定使用 doctrine/annotations,我建议您安装 spiral/attributes 以使用其中一个或两个。
以下是一个使用注解/属性的示例。
use Biurad\Annotations\AnnotationLoader; use Doctrine\Common\Annotations\AnnotationRegistry; use Flight\Routing\Annotation\Listener; use Spiral\Attributes\{AnnotationReader, AttributeReader}; use Spiral\Attributes\Composite\MergeReader; $reader = new AttributeReader(); // If you only want to use PHP 8 attribute support, you can skip this step and set reader to null. if (\class_exists(AnnotationRegistry::class)) $reader = new MergeReader([new AnnotationReader(), $reader]); $loader = new AnnotationLoader($reader); $loader->listener(new Listener(), 'my_routes'); $loader->resource('src/Controller', 'src/Bundle/BundleName/Controller'); $annotation = $loader->load('my_routes'); // Returns a Flight\Routing\RouteCollection class instance
您可以为注解加载器类添加更多监听器,以从同一位置加载所有注解/属性。还可以使用 populate()
路由收集方法或 group()
将注解的路由收集合并到默认路由收集中,或者简单地使用注解的路由收集作为默认路由器的路由收集。
最后,使用 RESTful 路由,如下例所示,使用 Flight\Routing\RouteCollection::resource
方法,这意味着路由对标准请求方法 Flight\Routing\Router::HTTP_METHODS_STANDARD
可用。
namespace Demo\Controller; class UserController { public function getUser(int $id): string { return "get {$id}"; } public function postUser(int $id): string { return "post {$id}"; } public function deleteUser(int $id): string { return "delete {$id}"; } }
使用 Flight\Routing\Handlers\ResourceHandler
添加路由。
use Flight\Routing\Handlers\ResourceHandler; $routes->add('/user/{id:\d+}', ['GET', 'POST'], new ResourceHandler(Demo\UserController::class, 'user'));
自版本 2.0 以来,Flight 路由非常稳定,可用于生产。请随意为项目做出贡献,报告错误,请求功能等。
在使用之前,请注意以下事项。
- 避免多次声明相同的动态路由模式(例如,
/hello/{name}
),如果选择使用相同路由路径和多个配置,则使用静态路径。- 如果选择使用默认处理器类的 RouteInvoker 类以外的不同解析器,应避免使用以
\
为前缀的路由处理器(例如,\HelloClass
或['\HelloClass', 'handle']
)。- 如果您再次决定使用自定义路由的处理程序解析器,我建议您包含默认路由的RouteInvoker类的静态
resolveRoute
方法。
📓 文档
关于如何使用这个库的详细文档,请查阅这个库的文档。还建议浏览测试目录中的单元测试。
🙌 赞助商
如果这个库已经进入您的项目,或者您有兴趣支持我们,请考虑捐赠以支持未来的开发。
👥 致谢
- Divine Niiquaye Ibok 是这个库的作者。
- 所有贡献者为这个项目做出了贡献。
📄 许可证
Flight Routing完全免费,并发布在BSD 3许可证下。