吉姆博/rapid

一个受Express.js启发的PHP中间件分发/路由器

dev-master 2016-08-17 15:54 UTC

This package is auto-updated.

Last update: 2024-09-18 04:15:17 UTC


README

Rapid是一个受Express.js启发的PSR-7 / 中间件分发器。Rapid的唯一外部依赖是PSR-7 Psr\HttpMessage 接口。Rapid需要PHP 7.0或更高版本。

安装

$ composer require offers/rapid

创建您的应用程序

$application = new Rapid\Application();
// add middlewares here
$application->run();

定义中间件

Rapid接受几个值来表示中间件。在Rapid期望中间件作为参数的任何地方,都可以使用以下任何一种方法:

传递一个实例

如果传递实例,则您的实例应该实现Rapid\MiddlewareInterface。此方法对于需要为依赖注入进行自定义实例化的实例很有用。

$application->use(new ExampleMiddleware());

传递一个类名

如果您的中间件不需要任何自定义实例化,则可以传递一个类名。除非系统实际上需要使用该给定的中间件,否则您的类将不会被实例化。

$application->use(ExampleMiddleware::class);

传递一个闭包

一个具有与Rapid\MiddlewareInterface兼容签名的闭包也可以使用。类型提示参数是可选的,但建议使用。

$application->use(function(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
    
});

使用中间件工厂

Rapid\Application 可选接受一个用于在指定类名时生成中间件的 callable。此可调用函数可以负责按您的要求进行连接和依赖注入。工厂应该是一个接受一个参数(类名)并返回正确连接的中间件的可调用函数。提供了一个用于便利的接口,但不是必需的,名为 Radpid\MiddlewareFactoryInterface

$application->setMiddlewareFactory($factory);

组合和路由中间件

中间件按照在您的应用程序引导中定义的顺序从上到下评估。中间件可以应用于每个请求,或使用传统的路由方法应用于一个 \Psr\HttpMessage\ServerRequestInterface 实例。所有中间件都将针对每个请求进行检查,并且允许和鼓励进行多次匹配。

将中间件应用于每个请求

$application = new Rapid\Application();
$application->use(new ExampleMiddleware());

基于方法和简单路径匹配中间件

$application->get("/test", TestMiddleware::class);

在任何方法和简单路径上匹配中间件

$application->all("/test", TestMiddleware::class);

在任何方法和简单路径上匹配中间件

$application->all("/test", TestMiddleware::class);

将一组中间件应用于给定的路径

$application->get("/test", [TestMiddleware::class, ExampleMiddleware::class]);

将中间件应用于同一路由上的多个方法

$application->route(["POST", "PUT"], "/test", TestMiddleware::class);

在同一个路由的同一方法上应用不同的中间件

$application->get("/test", GetMiddleware::class);
$application->post("/test", PostMiddleware::class);

路由

Rapid包含一个内置的路由/ URL 匹配器。

以下划线 / 开头且不包含以下说明的特殊操作符的 URL 被视为与请求路径的精确字符串匹配。在下面的示例中,如果请求 URI 的路径正好是 /test,则将调用 GetMiddleware。

$application->get("/test", GetMiddleware::class);

以下划线 / 开头并包含 {} 的 URL 将与系统生成的正则表达式匹配。带有 {} 的路径段被视为变量,并且这些段的值将作为属性设置在请求对象上。在下面的示例中,请求路径为 /test/myslug,结果将请求属性 slug 设置为 myslug

$application->get("/test/{slug}", GetMiddleware::class);

在给定路径前缀的末尾,可以添加一个特殊的标记 {?},它将任何路径匹配的剩余部分视为Rails风格的键值路由。在下面的示例中,请求路径为 /test/param1/value1/param2/value2,结果将请求属性 param1param2 分别设置为 value1value2注意:此路由匹配 0 个或多个选项,因此它还将匹配 /test

$application->get("/test{?}", GetMiddleware::class);

被反引号包围的路径规范被视为正则表达式,并按原样传递给 preg_match()。如果正则表达式匹配,则将 $matches 数组设置为请求属性。

$application->get("`/test.*?`", GetMiddleware::class);

使用自定义路由匹配器

Rapid 支持使用自定义的 callable 进行路由匹配。这在需要查询数据库以确定路由是否匹配的场景中可能很有用。该可调用函数应接受一个参数,即 \Psr\HttpMessage\RequestInterface,并返回 false(不匹配)或一个 \Psr\HttpMessage\RequestInterface,这可能就是它所接收的实例,或者是一个已经添加了必要属性的修改过的实例。提供了一个方便的接口 Rapid\RouteMatcherInterface,但不是必需的。

$application->get(function($request) {
    if ($request->getUri()->getPath = "/complex-logic") {
        return $request;    
    }
    return false;    
}, DataBackedMiddleware::class);

使用中间件管道

Rapid\Application 对象上的方便方法实际上是底层容器对象 Rapid\MiddlewarePipe 的代理。在启动时,可以直接使用中间件管道以获得更多灵活性和可重用性。

使用单个中间件创建一个新的中间件管道并使用它

$pipe = new \Radid\MiddlewarePipe(RunAlwaysMiddleware::class);
$application->use($pipe);

使用多个中间件创建一个新的中间件管道

$pipe = new \Radid\MiddlewarePipe([RunAlwaysMiddleware::class, AnotherMiddleware::class]);
$application->use($pipe);

向现有管道添加中间件

$pipe = new \Radid\MiddlewarePipe();
$myMiddleware = new MyMiddleware();
$pipe->pipe($myMiddleware);

中间件管道也完全支持路由。管道方法也将接受一个闭包。在闭包内部,你可以使用与应用程序对象上方便方法相同的语法。

$pipe = new \Radid\MiddlewarePipe();
$pipe->pipe(function() {
    $this->use(MiddlewareOne::class);
    $this->get('/prefix', PrefixMiddleware::class);
});

一个更具体的例子,使用管道进行组织。中间件管道可以在需要使用中间件的地方替换。

$publicPipe = new \Radid\MiddlewarePipe();
$publicPipe->pipe(function() {
   $this->get("/", HomepageMiddleware::class);
   $this->get("/login", LoginMiddleware::class);
});
$application->use($publicPipe);

$privateDirectoryPipe = (new Rapid\MiddlewarePipe())->pipe(function() {
    $this->get("/user", (new MiddlewarePipe)->pipe(function() {
        $this->use(AuthMiddleware::class);
        $this->get("/user/dashboard", DashBoardMiddleware::class);
        $this->get("/user/settings", SettingsMiddleware::class);    
    }));
});
$application->use($privateDirectoryPipe);

处理错误

Rapid 错误处理程序也被定义为中间件。错误中间件有一个稍微不同的签名,并在它们自己的 Rapid\Middleware\ErrorMiddlewareInterface 中进行描述。错误处理中间件的第一个参数是一个 Throwable

Rapid 在其调度周期中捕获 Throwable,因此 PHP 7.x 的 Error 抛出也会被捕获并由这些中间件处理。在调用第一个错误中间件之前,Rapid 将将 Throwable 设置为请求的属性,并将响应的状态码更改为适用的情况下的 404 或 500。Rapid 包含 2 个特殊的 Exceptions 用于路由问题:Rapid\Exception\MethodNotAllowedExceptionRapid\Exception\NoRouteMatchException

$application->use(ErrorMiddleware::class);

扩展基本应用程序

Rapid\Application 本身是一个非常简单的类。它提供了一个空的 init() 方法,该方法将被用于启动目的。默认构造函数故意不带参数,假设它可能会被覆盖。假设用户将扩展基本应用程序类,并在 init() 方法中实现所有中间件启动,并用参数如依赖注入容器覆盖构造函数,以在 init() 中使用。