snicco / http-routing
snicco 框架的 HTTP 和路由组件
Requires
- php: ^7.4|^8.0
- ext-filter: *
- ext-json: *
- ext-mbstring: *
- nikic/fast-route: 1.3.0
- psr/container: ^1.1
- psr/http-factory: ^1.0.0
- psr/http-message: ^1.0.0
- psr/http-server-handler: ^1.0.0
- psr/http-server-middleware: ^1.0.0
- snicco/psr7-error-handler: ^2.0
- snicco/str-arr: ^2.0
- webimpress/safe-writer: ^2.2
- webmozart/assert: ^1.10
Requires (Dev)
- phpunit/phpunit: ^9.5.13
- pimple/pimple: ^3.5
- snicco/http-routing-testing: ^2.0
- snicco/kernel: ^2.0
Suggests
- nyholm/psr7: To use as a fast PSR7 implementation.
Conflicts
- snicco/better-wp-api: <2.0.0-beta.9
- snicco/better-wp-cache: <2.0.0-beta.9
- snicco/better-wp-cache-bundle: <2.0.0-beta.9
- snicco/better-wp-cli: <2.0.0-beta.9
- snicco/better-wp-cli-testing: <2.0.0-beta.9
- snicco/better-wp-hooks: <2.0.0-beta.9
- snicco/better-wp-hooks-bundle: <2.0.0-beta.9
- snicco/better-wp-mail: <2.0.0-beta.9
- snicco/better-wp-mail-bundle: <2.0.0-beta.9
- snicco/better-wp-mail-testing: <2.0.0-beta.9
- snicco/better-wpdb: <2.0.0-beta.9
- snicco/better-wpdb-bundle: <2.0.0-beta.9
- snicco/blade-bridge: <2.0.0-beta.9
- snicco/blade-bundle: <2.0.0-beta.9
- snicco/content-negotiation-middleware: <2.0.0-beta.9
- snicco/debug-bundle: <2.0.0-beta.9
- snicco/default-headers-middleware: <2.0.0-beta.9
- snicco/eloquent: <2.0.0-beta.9
- snicco/encryption-bundle: <2.0.0-beta.9
- snicco/event-dispatcher: <2.0.0-beta.9
- snicco/event-dispatcher-testing: <2.0.0-beta.9
- snicco/guests-only-middleware: <1.0.0
- snicco/http-routing-bundle: <2.0.0-beta.9
- snicco/http-routing-testing: <2.0.0-beta.9
- snicco/https-only-middleware: <2.0.0-beta.9
- snicco/illuminate-container-bridge: <2.0.0-beta.9
- snicco/kernel: <2.0.0-beta.9
- snicco/kernel-testing: <2.0.0-beta.9
- snicco/method-override-middleware: <2.0.0-beta.9
- snicco/minimal-logger: <2.0.0-beta.9
- snicco/must-match-route-middleware: <2.0.0-beta.9
- snicco/no-robots-middleware: <2.0.0-beta.9
- snicco/open-redirect-protection-middleware: <2.0.0-beta.9
- snicco/payload-middleware: <2.0.0-beta.9
- snicco/pimple-bridge: <2.0.0-beta.9
- snicco/psr7-error-handler: <1.0.0
- snicco/redirect-middleware: <2.0.0-beta.9
- snicco/session: <2.0.0-beta.9
- snicco/session-bundle: <2.0.0-beta.9
- snicco/session-psr16-bridge: <2.0.0-beta.9
- snicco/session-testing: <2.0.0-beta.9
- snicco/session-wp-bridge: <2.0.0-beta.9
- snicco/share-cookies-middleware: <2.0.0-beta.9
- snicco/signed-url: <2.0.0-beta.9
- snicco/signed-url-psr15-bridge: <2.0.0-beta.9
- snicco/signed-url-psr16-bridge: <2.0.0-beta.9
- snicco/signed-url-testing: <2.0.0-beta.9
- snicco/signed-url-wp-bridge: <2.0.0-beta.9
- snicco/templating: <2.0.0-beta.9
- snicco/templating-bundle: <2.0.0-beta.9
- snicco/testable-clock: <2.0.0-beta.9
- snicco/testing-bundle: <2.0.0-beta.9
- snicco/trailing-slash-middleware: <2.0.0-beta.9
- snicco/wp-auth-only-middleware: <2.0.0-beta.9
- snicco/wp-capability-middleware: <2.0.0-beta.9
- snicco/wp-capapility-middleware: <1.0.0
- snicco/wp-guests-only-middleware: <2.0.0-beta.9
- snicco/wp-nonce-middleware: <2.0.0-beta.9
- dev-master
- v2.0.0-beta.9
- v2.0.0-beta.8
- v2.0.0-beta.7
- v2.0.0-beta.6
- v2.0.0-beta.5
- v2.0.0-beta.4
- v2.0.0-beta.3
- v2.0.0-beta.2
- v2.0.0-beta.1
- v1.10.1
- v1.10.0
- v1.9.1
- v1.9.0
- v1.8.1
- v1.8.0
- v1.7.0
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- dev-beta
This package is auto-updated.
Last update: 2024-09-07 14:27:57 UTC
README
HTTP-Routing 组件是 Snicco 项目 的一个有观点的库,它结合了基于 FastRoute
构建的路由系统和强大的 PSR-15 中间件调度器。
虽然不是必需的,但它被特意构建以支持像 WordPress 这样的旧版 CMS,在这些 CMS 中,您无法完全控制请求-响应生命周期。
特性
- 丰富的路由配置 API
- URL 生成/反向路由
- 按路由附加中间件
- 路由分组
- 在生产环境中完全缓存
- 针对旧版 CMS 的管理区域进行特殊处理(如果适用)
- 等等。
目录
安装
composer require snicco/http-routing
路由
创建路由器
路由子组件的中心类是 Router
门面类。(不是 Laravel 门面)
Router
作为一个工厂,为路由系统的不同部分提供服务。
为了实例化一个 Router
,我们需要以下合作者
URLGenerationContext
,这是一个配置 URL 生成的 值对象。RouteLoader
,负责加载和配置您的路由(如果还没有缓存的话。)RouteCache
,负责在生成环境中缓存路由定义。AdminArea
的实例,它作为路由系统和旧版 CMS 管理区域之间的桥梁。
use Snicco\Component\HttpRouting\Routing\Cache\FileRouteCache;use Snicco\Component\HttpRouting\Routing\Cache\NullCache; use Snicco\Component\HttpRouting\Routing\RouteLoader\DefaultRouteLoadingOptions; use Snicco\Component\HttpRouting\Routing\RouteLoader\PHPFileRouteLoader; use Snicco\Component\HttpRouting\Routing\Router; use Snicco\Component\HttpRouting\Routing\UrlGenerator\UrlGenerationContext; $context = new UrlGenerationContext('snicco.io'); $route_loading_options = new DefaultRouteLoadingOptions( '/api/v1' // the base-prefix for API routes ); $route_loader = new PHPFileRouteLoader( [__DIR__.'/routes'], // directories of "normal" routes [__DIR__.'/routes/api'], // directories of "API" routes, optional $route_loading_options, ); // during development $route_cache = new NullCache(); // during production $route_cache = new FileRouteCache('/path/to/cache_dir/route_cache.php'); $router = new Router( $context, $route_loader, $route_cache // $admin_area This is a simple interface that you can implement if you use admin routes. );
一旦我们有了我们的 Router
,我们就可以使用它来实例化路由系统的不同部分。
use Snicco\Component\HttpRouting\Routing\Router; /** * @var Router $router */ $router = /* */ $router->routes(); // Returns an instance of RouteCollection $router->urlGenerator(); // Returns an instance of UrlGenerator $router->urlMatcher(); // Returns an instance of UrlMatcher $router->adminMenu(); // Returns an instance of AdminMenu
定义路由
包含的 PHPFileRouteLoader
将在提供的路由目录中的每个目录内搜索具有 .php
扩展名的文件。不使用嵌套目录。
目前,我们假设以下目录结构
your-project-root
├── routes/
│ ├── frontend.php
│ ├── admin.php
├── api-routes/
│ ├── v1.php
└── ...
每个路由目录内的文件都必须返回一个闭包,该闭包接受一个 RoutingConfigurator
实例。
// ./routes/frontend.php use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; return function (WebRoutingConfigurator $configurator ) { // }
特殊情况下,admin.php
路由文件将接收一个 AdminRoutingConfigurator
实例。
// ./routes/admin.php use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\AdminRoutingConfigurator; return function (AdminRoutingConfigurator $configurator ) { // }
RouteLoadingOptions
是一个 值对象,允许您为所有路由自定义一些通用设置,例如自动添加具有路由文件名称的中介。
查看 DefaultRouteLoadingOptions
以获取示例。
定义 HTTP 动词
use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator = /* */ $configurator->get( 'posts.index', // The route name MUST BE UNIQUE. '/posts', // The route pattern [PostController::class, 'index'] // The controller for the route. ); $configurator->post('posts.create', '/posts', [PostController::class, 'create']); $configurator->put('posts.update', '/posts/{post_id}', [PostController::class, 'update']); $configurator->delete('posts.delete', '/posts/{post_id}', [PostController::class, 'delete']); $configurator->patch(/* */); $configurator->options(/* */); $configurator->any(/* */); $configurator->match(['GET', 'POST'], /* */);
路由参数
HTTP-Routing 组件的语法提供了一种替代原生语法的语法。这非常具有意见性,但我们认为 FastRoute
的语法有些冗长,尤其是在处理可选段和正则表达式要求时。
为了获得最佳性能,所有路由将在缓存之前编译以匹配 FastRoute 的原生语法。
- 在
{...}
中包含的路由段是必需的。 - 在
{...?}
中包含的路由段是可选的。
$configurator->get( 'route_name', '/posts/{post}/comments/{comment?}', PostController::class );
上述路由定义将匹配 /posts/1/comments/2
和 /posts/1/comments
。
捕获的参数将可用于配置的控制器。
可以使用路由段组合使用尾部斜杠。
$configurator->get( 'route_name', '/posts/{post}/comments/{comment?}/', PostController::class );
上述路由定义将匹配 /posts/1/comments/2/
和 /posts/1/comments/
。
可选段只能出现在路由模式的末尾。
正则表达式约束
use Snicco\Component\HttpRouting\Routing\Route\Route; use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator->get( 'route1', '/user/{id}/{name}', PostController::class )->requirements([ 'id' => '[0-9]+', 'name' => '[a-z]+' ]); /** @var Route $route */ $route = $configurator->get(/* */); // The Route class contains a couple of helper methods. $route->requireAlpha('segment_name'); $route->requireNum('segment_name'); $route->requireAlphaNum('segment_name'); $route->requireOneOf('segment_name', ['category-1', 'category-2']);
添加中介
可以为每个路由单独配置中介。
中介可以是 PSR-15 中介 的完全限定类名或稍后将解析为 PSR-15 中介类名的别名。
可以将参数作为逗号分隔的列表传递给中介(构造函数),并在 :
之后传递。在实例化中介并传递参数之前执行以下转换
- (string) true => (bool) true
- (string) false => (bool) false
- (string) numeric => numeric
use Snicco\Component\HttpRouting\Routing\Route\Route; use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator->get('route1', '/route1', InvokableController::class) // middleware as an alias. ->middleware('auth') // adding multiple middleware ->middleware([PSR15MiddlewareOne::class, PSR15MiddlewareTwo::class]); // passing comma separated arguments ->middleware('can:manage_options,1');
添加条件
除了通过其 URL 模式匹配路由外,还可以指定路由条件。
路由条件是任何实现 RouteCondition
的类。
use Snicco\Component\HttpRouting\Routing\Route\Route; use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator->get('route1', '/route1', InvokableController::class) ->condition(OnlyIfUserAgentIsFirefox::class) // passing arguments ->condition(OnlyIfHeaderIsPresent::class, 'X-CUSTOM-HEADER');
路由分组
可以使用路由组将具有类似属性的路线分组在一起。
以下属性目前可以以某种形式分组
- 中介:将合并为组中的所有路由。
- URL 前缀:将添加到组中的所有 URL 模式。
- 路由名称:将连接到所有路由。
- 命名空间:将应用于所有路由,但可以在每个路由的基础上覆盖。
支持嵌套路由组。
use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator ->name('users') ->prefix('/base/users') ->middleware('auth') ->namespace('App\\Http\\Controllers') ->group(function (WebRoutingConfigurator $configurator) { // The route name will be users.profile // The route pattern will be /base/users/profile/{user_id} // The controller definition will be [App\\Http\\Controllers\\ProfileController::class, 'index'] // The middleware is [auth, auth-confirmed] $configurator->get('profile', '/profile/{user_id}', 'ProfileController@index') ->middleware('auth-confirmed'); $configurator->/* */->group(/* */); });
控制器
控制器是附加到路由的类方法。
控制器将用于将 PSR-7 服务器请求 转换为 PSR-7 响应。(稍后介绍)
现在,最重要的是如何定义控制器以及控制器中将有哪些参数可用。
namespace App\Controller; use Snicco\Component\HttpRouting\Http\Psr7\Request; class RouteController { public function __invoke(Request $request){ // } public function withoutRequest(string $route_param){ // } public function withRequestTypehint(Request $request, string $route_param){ // } } // Valid ways to define a controller: $configurator->get('route1', '/route-1', RouteController::class) $configurator->get('route2', '/route-2/{param}', [RouteController::class, 'withoutRequest']); $configurator->get('route3', '/route3/{param}', 'App\\Controller\\RouteController@withRequestTypehint'); // or $configurator->namespace('App\\Controller')->get('route3', '/route3/{param}', 'RouteController@withRequestTypehint');
如果使用完全限定的类名定义控制器,则它必须有一个 __invoke
方法。
可以省略控制器,在这种情况下,将向路由添加一个回退控制器。回退控制器将始终返回一个DelegatedResponse
实例,该实例可用于表示(给另一个系统)当前请求不应被处理(由您的代码)。
传递给所有控制器方法的第一个参数是Snicco\Component\HttpRouting\Http\Psr7\Request
实例(如果控制器方法有此类型提示)。
捕获的路由段按顺序传递给控制器方法。方法参数名称和路由定义中的段名称不重要。
捕获的路由段始终是字符串(在FastRoute中),但为了方便,数值会被转换为整数。
路由条件也可以返回“捕获的参数”。如果一个路由有返回参数的条件,这些参数将在捕获的URL参数之后传递给控制器方法。
重定向路由
您可以直接在路由文件中配置重定向。不是定义专用控制器,所有重定向路由都将使用RedirectController
来直接创建一个RedirectResponse
。
use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator->redirect('/foo', '/bar', 301); $configurator->redirectAway('/foo', 'https://external-site.com', 302); $configurator->redirectToRoute('/foo', 'route1', 307);
视图路由
如果您只想为给定的URL返回一个简单的模板而不涉及太多逻辑,您可以使用路由配置器上的view()
方法。
use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\WebRoutingConfigurator; /** * @var WebRoutingConfigurator $configurator */ $configurator->view('/contact', 'contact.php');
当此路由匹配时,它将返回一个ViewResponse
实例。如何将其转换为底层模板取决于您。您可能需要在自定义中间件中使用您喜欢的模板引擎来实现这一点。
管理路由
定义在admin.php
文件中的路由具有特殊之处,因为它们可以用来创建指向CMS(如WordPress)管理区域的路由,通常您无法控制“路由”。
您甚至可以直接从路由定义中创建管理菜单项。
所有这些实现细节都被AdminArea
接口和AdminMenu
接口抽象。
通过使用AdminRoutingConfigurator
来配置管理路由。
管理路由仅限于GET
请求。
您将使用AdminRoutingConfigurator::page()
和AdminRoutingConfigurator::subPage()
方法而不是使用WebRoutingConfigurator::get()
方法。
以下是如何在WordPress中使用它的示例,在管理区域中使用page
查询变量来进行路由。查看WPAdminArea
,这是AdminArea
接口在WordPress中的实现。
// .routes/admin.php use Snicco\Component\HttpRouting\Routing\Admin\AdminMenu; use Snicco\Component\HttpRouting\Routing\Admin\AdminMenuItem; use Snicco\Component\HttpRouting\Routing\RoutingConfigurator\AdminRoutingConfigurator; /** * @var AdminRoutingConfigurator $configurator */ $configurator->name('my-plugin') ->middleware('my-plugin-middleware') ->group(function (AdminRoutingConfigurator $configurator) { $parent_route = $configurator ->page('overview', '/admin.php/overview', OverViewController::class) ->middleware('parent-middleware'); $configurator->page( 'settings', '/admin.php/settings', SettingsController::class, [ // Explicitly configure menu item attributes. AdminMenuItem::MENU_TITLE => 'Custom settings title' ] $parent_route // Set a parent route to create a menu hierarchy. Middleware is inherited. ); });
在您的默认WordPress安装中,这些路由将匹配以下路径
/wp-adming/admin.php?page=overview
/wp-adming/admin.php?page=settings
根据您的路由名称和路由模式,将自动将一个 AdminMenuItem
实例添加到通过 Router
可用的 AdminMenu
。
API 路由
API 路由目录中的路由文件与“常规”路由之间的区别是,将使用 RouteLoadingOptions::getApiRouteAttributes()
方法为每个路由应用默认设置。
这允许例如
- 为所有路由添加基础前缀,如
/api
- 以
api.
作为路由名称的前缀 - 从文件名中解析版本号并将其作为前缀应用
/api/v1
使用 API 路由完全是可选的。
路由缓存
上述所有内容 都将在生产中缓存在一个单一的 PHP 文件中,该文件可以通过 OPcache 非常快速地返回。
出于这个原因,此包有意不支持 Closures
作为“路由控制器”。在 PHP 中无法原生序列化 Closures
。
在内部,FastRoute
只包含每个路由的名称。一旦匹配到某个路由,将仅对该单个路由进行初始化并“运行”。
随着您的应用程序中路由数量的增加,这提供了显著的性能提升。
请查看 SerializedRouteCollection
以获取详细信息。
匹配路由
对 Router::urlMatcher()
的第一次调用将延迟加载和配置所有路由(或返回缓存的那些)。
use Snicco\Component\HttpRouting\Routing\UrlMatcher\RoutingResult; use Snicco\Component\HttpRouting\Routing\UrlMatcher\UrlMatcher; $router = /* */ /** @var $url_matcher */ $url_matcher = $router->urlMatcher(); $psr_server_request = /* create any psr7 server request here. */ $routing_result = $url_matcher->dispatch($psr_server_request); $routing_result->isMatch(); $routing_result->route(); $routing_result->decodedSegments();
反向路由/URL 生成
路由系统始终是双向的
- URL > 路由
- 路由名称 + 参数 > URL
FastRoute
只提供第一部分。此包填补了这一空白。
对 Router::urlGenerator()
的第一次调用将延迟加载和配置所有路由(或返回缓存的那些)。
在生成 URL 时考虑 正则表达式约束,如果提供的值会导致不匹配路由,将抛出异常。
use Snicco\Component\HttpRouting\Routing\Router; use Snicco\Component\HttpRouting\Routing\UrlGenerator\UrlGenerator; // In a route file: $configurator->get('route1', '/route1/{param1}/{param2}', RouteController::class) ->requireAlpha('param1') ->requireNum('param2'); /** * @var Router $router */ $router = /* */ $url_generator = $router->urlGenerator(); $url = $url_generator->toRoute('route1', ['param1' => 'foo', 'param2' => '1']); var_dump($url); // /route1/foo/1 $url = $url_generator->toRoute('route1', ['param1' => 'foo', 'param2' => '1'], UrlGenerator::ABSOLUTE_URL); var_dump($url); // https://snicco.io/route1/foo/1 (host and scheme depend on your UrlGenerationContext) // This will throw an exception because param2 is not a number $url_generator->toRoute('route1', ['param1' => 'foo', 'param2' => 'bar']);
管理员菜单
如果您正在使用 管理路由,则将根据您的路由定义自动配置一个 AdminMenu
实例。
您可以使用 AdminMenu
对象来配置某些外部系统或旧版 CMS(如果适用)。
对 Router::adminMenu()
的第一次调用将延迟加载和配置所有路由(或返回缓存的那些)。
/** * @var Router $router */ $router = /* */ $admin_menu = $router->adminMenu(); foreach ($admin_menu->items() as $menu_item) { // register the menu item somewhere. }
PSR-15 中间件分发器
此包附带一个非常强大的 PSR-15 中间件分发器,该分发器已集成了配置的路由系统。
核心是 MiddlewarePipeline
。
创建中间件管道
中间件管道需要一个 PSR-11 容器 来延迟解析您的控制器和中间件。
此外,还需要一个 HTTPErrorHanlder
实例来处理每个中间件的异常。
use Psr\Container\ContainerInterface; use Snicco\Component\HttpRouting\Middleware\MiddlewarePipeline; use Snicco\Component\Psr7ErrorHandler\ProductionErrorHandler; /** * @var ContainerInterface $psr_11_container */ $psr_11_container = /* */ /** * @var ProductionErrorHandler */ $psr7_error_handler = /* */ $pipeline = new MiddlewarePipeline( $psr_11_container, $psr7_error_handler );
管道请求
在基本层面上,中间件管道接受一个 PSR-7 服务器请求,将其通过多个PSR-15 中间件,并返回一个PSR-7 响应。如何发送该响应对象取决于您。
use Snicco\Component\HttpRouting\Http\Psr7\Request; use Snicco\Component\HttpRouting\Middleware\MiddlewarePipeline; /** * @var MiddlewarePipeline $pipeline */ $pipeline = /* */ $response = $pipeline ->send($server_request) ->through([ Psr15MiddlewareOne::class, Psr15MiddlewareTwo::class, ])->then(function (Request $request) { // Throw exception or return a default response. throw new RuntimeException('Middleware pipeline exhausted without returning response.'); });
为了将中间件管道与我们的路由系统连接,我们使用此包内建的 PSR-15 中间件。
RoutingMiddleware
负责将管道中的当前请求匹配到 路由系统 的某个路由。
use Snicco\Component\HttpRouting\Middleware\RoutingMiddleware; $routing_middleware = new RoutingMiddleware( $router->urlMatcher(); );
RouteRunner
负责执行匹配的路由。
如果没有匹配到路由,将返回一个 DelegatedResponse
实例。
如果匹配到路由,将发生以下操作
- 将解析匹配路由的所有中间件。
- 创建一个新的(内部)中间件管道,通过所有路由中间件传输请求。
- 内部中间件管道的最后一步将解析容器中的路由控制器并执行它。
为了实例化 RouteRunner
,我们首先需要一个 MiddlewareResolver
。
use Snicco\Component\HttpRouting\Middleware\RouteRunner; $pipeline = /* This can be the same pipeline we created initially. The pipeline is immutable anyway. */ $psr_11_container = /* */ $middleware_resolver = /* */ $route_runner = new RouteRunner($pipeline, $middleware_resolver, $psr_11_container); $response = $pipeline->send($server_request) ->through([ $routing_middleware, $route_runner ])->then(function () { throw new RuntimeException('Middleware pipeline exhausted.'); });
MiddlewareResolver
正如类名所示,MiddlewareResolver
负责解析应用于单个路由和/或请求的所有中间件。
use Snicco\Component\HttpRouting\Middleware\MiddlewareResolver; // The following four middleware groups can be set to always be applied, even if no route matched. $always_run = [ 'global' 'frontend', 'admin', 'api' ] // This configures the short aliases we used in our route definitions $middleware_aliases = [ 'auth' => AuthenticateMiddleware::class ] // An alias can also be a middleware group. // Middleware groups can contain other groups. $middleware_groups = [ 'group1' => [ 'auth', // group contains alias SomePsr15Middleware::class ], 'group2' => [ 'group1,' // fully contains group1 SomeOtherPsr15Middleware::class ], 'global' => [], 'frontend' => [ ], 'api' => [ RateLimitAPI::class ], 'admin' => [] ]; // A list of class names, the 0-index has the highest priority, meaning that it will // always run first. $middleware_priority = [ SomePsr15Middleware::class, SomeOtherPsr15Middleware::class ]; $middleware_resolver = new MiddlewareResolver( $always_run, $middleware_aliases, $middleware_groups, $middleware_priority );
中间件解析器可以被缓存以最大化性能。
缓存中间件解析器意味着,对于您的应用程序中的每个路由,中间件都已经递归解析,分组已展开,别名已解析等。
use Snicco\Component\HttpRouting\Middleware\MiddlewareResolver; $middleware_resolver = new MiddlewareResolver(); $store_me = $middleware_resolver->createMiddlewareCache( $router->routes(), $psr_11_container ); file_put_contents('/path/to/cache-dir/middleware-cache.php', '<?php return ' . var_export($store_me, true) . ';'); list($route_map, $request_map) = require '/path/to/cache-dir/middleware-cache.php'; $cached_resolver = MiddlewareResolver::fromCache($route_map, $request_map);
PSR 工具
此包包含一些扩展 PSR 接口以提供一些实用辅助器的类。
使用它们完全是可选的
- 抽象的
Middleware
和抽象的Controller
可以被扩展。它们都提供了对ResponseUtils
类的访问,并包含对URLGenerator
的引用。 Request
类包装了任何 PSR-7 请求,并提供了一些在 PSR-7 接口中未定义的有用方法。Response
类包装了任何 PSR-7 响应,并提供了一些在 PSR-7 接口中未定义的有用方法。
贡献
此存储库是 Snicco 项目 开发存储库的只读分割。
报告问题和发送拉取请求
请在 Snicco monorepo 中报告问题。
安全性
如果您发现安全漏洞,请遵循我们的 披露程序。