路由服务提供者
Testing Is Documentation
路由主要由路由服务来接入框架,可以做一些设置。
php
namespace App\Infra\Provider;
use App\Auth\Middleware\Auth;
use Leevel\Router\RouterProvider;
use Leevel\Session\Middleware\Session;
class Router extends RouterProvider
{
/**
* 控制器相对目录.
*/
protected ?string $controllerDir = 'Controller';
/**
* 应用是否带有默认应用命名空间.
*/
protected bool $withDefaultAppNamespace = true;
/**
* 中间件分组.
*
* - 分组可以很方便地批量调用组件.
*/
protected array $middlewareGroups = [
// web 请求中间件
'web' => [
'session',
],
// api 请求中间件
'api' => [],
];
/**
* 中间件别名.
*
* - HTTP 中间件提供一个方便的机制来过滤进入应用程序的 HTTP 请求.
* - 例外在应用执行结束后响应环节也会调用 HTTP 中间件.
*/
protected array $middlewareAlias = [
'auth' => Auth::class,
'session' => Session::class,
];
/**
* 基础路径.
*/
protected array $basePaths = [
'api/demo' => [
'middlewares' => 'api',
],
'apiQL/v*' => [
'middlewares' => 'auth',
],
'/app:*/apiQL/v*' => [
'middlewares' => 'auth',
],
];
/**
* 分组.
*/
protected array $groups = [
'pet' => [],
'store' => [],
'user' => [],
'/apiQL/v1' => [
'middlewares' => 'api',
],
'apiQL/v2' => [
'middlewares' => 'api',
],
'/web/v1' => [
'middlewares' => 'web',
],
'web/v2' => [
'middlewares' => 'web',
],
];
/**
* {@inheritDoc}
*/
public function bootstrap(): void
{
parent::bootstrap();
}
/**
* {@inheritDoc}
*/
public function getRouters(): array
{
return parent::getRouters();
}
}
Uses
php
<?php
use Leevel\Di\Container;
use Leevel\Kernel\App;
use Leevel\Kernel\Utils\Api;
use Leevel\Router\Router;
use Leevel\Router\RouterProvider;
use Leevel\Router\ScanRouter;
use Tests\Router\Middlewares\Demo1;
use Tests\Router\Middlewares\Demo2;
use Tests\Router\Middlewares\Demo3;
基本使用
QueryPHP 路由最终结果主要由 base_paths
、groups
和 routers
构成。
fixture 定义
路由服务提供者 Tests\Router\RouterProvider1
php
namespace Tests\Router;
class RouterProvider1 extends RouterProvider
{
protected ?string $controllerDir = 'Tests\\Router\\Apps';
protected array $middlewareGroups = [
'group1' => [
'demo1',
'demo2',
],
'group2' => [
'demo1',
'demo3:10,world',
],
'group3' => [
'demo1',
'demo2',
'demo3:10,world',
],
];
protected array $middlewareAlias = [
'demo1' => Demo1::class,
'demo2' => Demo2::class,
'demo3' => Demo3::class,
];
protected array $basePaths = [];
protected array $groups = [
'pet' => [],
'store' => [],
'user' => [],
'/api/v1' => [
'middlewares' => 'group1',
],
'/api/v2' => [
'middlewares' => 'group2',
],
'/api/v3' => [
'middlewares' => 'demo1,demo3:30,world',
],
'/api/v3' => [
'middlewares' => ['demo1', 'group3'],
],
'/api/v4' => [
'middlewares' => 'notFound',
],
];
public function bootstrap(): void
{
parent::bootstrap();
}
public function getRouters(): array
{
return parent::getRouters();
}
protected function makeScanRouter(): ScanRouter
{
$scanRouter = parent::makeScanRouter();
$scanRouter->setControllerDir('');
return $scanRouter;
}
}
路由注解缓存结果 tests/Router/Apps/AppScanRouter/data.json
json
{
"base_paths": {
"\/^\\\/api\\\/v1(\\S*)\\\/$\/": {
"middlewares": {
"handle": [
"Tests\\Router\\Middlewares\\Demo2@handle"
],
"terminate": [
"Tests\\Router\\Middlewares\\Demo1@terminate",
"Tests\\Router\\Middlewares\\Demo2@terminate"
]
}
},
"\/^\\\/api\\\/v2(\\S*)\\\/$\/": {
"middlewares": {
"handle": [
"Tests\\Router\\Middlewares\\Demo3@handle:10,world"
],
"terminate": [
"Tests\\Router\\Middlewares\\Demo1@terminate"
]
}
},
"\/^\\\/api\\\/v3(\\S*)\\\/$\/": {
"middlewares": {
"handle": [
"Tests\\Router\\Middlewares\\Demo2@handle",
"Tests\\Router\\Middlewares\\Demo3@handle:10,world"
],
"terminate": [
"Tests\\Router\\Middlewares\\Demo1@terminate",
"Tests\\Router\\Middlewares\\Demo2@terminate"
]
}
}
},
"groups": [
"\/pet",
"\/store",
"\/user",
"\/api\/v1",
"\/api\/v2",
"\/api\/v3",
"\/api\/v4"
],
"routers": {
"get": {
"a": {
"\/api\/v1": {
"\/api\/v1\/petLeevel\/{petId:[A-Za-z]+}\/": {
"bind": "\\Tests\\Router\\Apps\\AppScanRouter\\Controllers\\Pet@petLeevel",
"var": [
"petId"
]
},
"regex": [
"~^(?|\/api\/v1\/petLeevel\/([A-Za-z]+)\/)$~x"
],
"map": [
{
"2": "\/api\/v1\/petLeevel\/{petId:[A-Za-z]+}\/"
}
]
}
}
}
}
}
php
public function testBaseUse(): void
{
$container = Container::singletons();
$app = new App($container, '');
$app->setAppPath(__DIR__.'/Apps/AppScanRouter');
$app->setPath(__DIR__.'/Apps/AppScanRouter');
$app->setRouterCachedPath(__DIR__.'/router_cached.php');
$container->instance('app', $app);
$container->instance('router', $router = $this->createRouter($container));
$provider = new RouterProvider1($container);
self::assertNull($provider->register());
self::assertNull($provider->bootstrap());
$data = file_get_contents(__DIR__.'/Apps/AppScanRouter/data.json');
self::assertSame(
$data,
$this->varJson(
[
'base_paths' => $router->getBasePaths(),
'groups' => $router->getGroups(),
'routers' => $router->getRouters(),
]
)
);
Container::singletons()->clear();
}