bobbynarvy/highway

PHP 简单路由。兼容 PSR-7 和 PSR-15。

0.5.0 2018-10-20 00:37 UTC

This package is auto-updated.

Last update: 2024-09-29 04:09:04 UTC


README

Build Status

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)。有关更多信息,请参阅 许可文件