bobbynarvy / highway
PHP 简单路由。兼容 PSR-7 和 PSR-15。
Requires
- php: ^7.1
- psr/http-message: ^1.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- zendframework/zend-diactoros: ^2.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-29 04:09:04 UTC
README
PHP 简单路由。兼容 PSR-7 和 PSR-15。
Highway 是一个用于将 HTTP 请求路由到其处理器的组件。
安装
通过 Composer
$ composer require bobbynarvy/highway
使用方法
Highway 可以用作独立路由器,它可以集成到任何 PHP 脚本中,也可以用作 PSR-15 中间件。
基本用法:作为独立路由器
使用路由器的基本场景可能如下所示
// on index.php... use Highway\{Route, Router}; // PSR-7 and PSR-15 interfaces use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; // Implementations of PSR-7 and PSR-15 use Zend\Diactoros\Response\HtmlResponse; use Zend\Diactoros\{ServerRequestFactory, Response}; use Zend\HttpHandlerRunner\Emitter\SapiEmitter; // Create an instance of PSR-7 ServerRequestInterface object // using Zend\Diactoros $request = ServerRequestFactory::fromGlobals( $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES ); // Create a new instance of Highway\Router $router = new Router; // Set the handler for HTTP requests going to the root path $router->get("/", function (ServerRequestInterface $request) { // Return an instance of HtmlResponse, an implementation of // Psr\Http\Message\ResponseInterface; return new HtmlResponse("<h1>It works!</h1>"); }); // Set the handler for a route with parameters $router->get("/users/{id}/messages/{num}", function (ServerRequestInterface $request) { // Assign the attributes to their respective variables using the // getAttribute() method of Psr\Http\Message\ServerRequestInterface $id = $request->getAttribute("id"); $num = $request->getAttribute("num"); return new HtmlResponse("<h1>ID: $id</h1> <h1>NUM: $num</h1>"); }); // Get the response to the request that matches a defined route $response = $router->match($request)->handle($request); // Emit the response to the HTTP client $emitter = new SapiEmitter; $emitter->emit($response);
注意:上面的示例假设启用了 URL 重写,以从 URI 中移除 'index.php'
方法
要注册路由,可以使用与 HTTP 方法相对应的方法使用路由器
$router->get($path, $handler); $router->post($path, $handler); $router->put($path, $handler); $router->patch($path, $handler); $router->delete($path, $handler); $router->options($path, $handler);
多个 HTTP 方法也可以映射为以相同的方式响应。例如
$router->map(["GET", "POST"], $handler);
路由前缀
可以使用路由器为给定路径添加前缀
$router->with("/users/{id}", function(Router $router) { // will respond to /users/{id}/likes routes $router->get("/likes", $likeHandler); // will respond to /users/{id}/friends/{fid} routes $router->get("/friends/{fid}", $friendHandler); });
处理器
处理器与路由一起传递给路由器。它们定义了当路由器找到与请求匹配的路由时调度的操作。
闭包
处理器可以通过接收实现 PSR-7 ServerRequestInterface 的对象并返回实现 PSR-7 ResponseInterface 的对象的闭包来定义。
use Zend\Diactoros\Response\HtmlResponse; $handler = function (ServerRequestInterface $request) { // return an instance of HtmlResponse, an implementation of // Psr\Http\Message\ResponseInterface; return new HtmlResponse("<h1>It works!</h1>"); }
PSR-15 RequestHandlerInterface
可以使用实现 PSR-15 RequestHandlerInterface 的对象来定义处理器。
use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\RequestHandlerInterface; use Zend\Diactoros\Response\HtmlResponse; $handler = new class implements RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface { return new HtmlResponse("<h1>It works!</h1>"); } };
请求参数
可以使用 PSR-7 ServerRequestInterface 对象的 getAttribute
方法访问请求参数
$router->get("/users/{id}/messages/{num}", function (ServerRequestInterface $request) { $id = $request->getAttribute("id"); /* ... */ });
作为 PSR-15 中间件
Highway 可以用于创建符合 PSR-15 的中间件。与将自身分配和调度中间件的其它路由器实现不同,Highway 本身 就是 一个中间件!
/*...*/ use Highway\{Router, RouterMiddleware}; use Zend\Diactoros\Response\HtmlResponse; /*...*/ $routerMiddleware = RouterMiddleware::create(function (Router $router) { $router->get("/", function (ServerRequestInterface $request) { return new HtmlResponse("<h1>It works!</h1>"); }); /* ... */ });
Highway 可以与其它可重用的 PSR-15 中间件一起使用。例如,使用 middlewares/utils
Dispatcher
/*...*/ use Middlewares\Utils\Dispatcher; /*...*/ $routerMiddleware = RouterMiddleware::create(function (Router $router) { // define routes... }); $response = Dispatcher::run([ $someAuthMiddleware, $someLoggingMiddleware, $routerMiddleware ]);
测试
$ composer test {file or path to test}
致谢
许可协议
MIT 许可协议 (MIT)。有关更多信息,请参阅 许可文件