asko / router
一个无需配置的依赖注入的最小化PHP路由器
Requires
- php: >=8.2
Requires (Dev)
- phpunit/phpunit: ^10
README
一个内置无需配置的依赖注入的PHP路由器。
安装
composer require asko/router
用法
最基本的用法示例如下
use Asko\Router\Router; $router = new Router(); $router->get("/hello/{who}", function(string $who) { echo "Hello, {$who}"; }); $router->dispatch();
所有HTTP方法都受支持: get
、head
、post
、put
、delete
、patch
、options
、trace
。要捕获任何HTTP方法,请使用 any
。
要设置404处理器,请使用not_found
方法,该方法仅接受一个可调用项作为其唯一参数。
可调用项
您可以将3种不同类型的可调用项传递给路由器。
控制器
控制器是用于将相似路由分组在一起的类,例如,如果您有管理页面路由,那么创建一个AdminController
类是有意义的,其中每个方法代表一个单独的路由。要使用控制器类与路由器一起使用,您需要传递一个数组作为可调用项,其中第一个元素是类常量,第二个是方法名称,如下所示
use Asko\Router\Router; class AdminController { public function login() { echo "Login page goes here."; } } $router = new Router(); $router->get("/admin/login", [AdminController::class, "login"]); $router->dispatch();
函数
函数是常规PHP函数,您将函数名称作为可调用项传递。如果您想进行更多函数式编程,这将很有用
use Asko\Router\Router; function hello_world() { echo "Hello, World!"; } $router = new Router(); $router->get("/hello-world", "hello_world"); $router->dispatch();
闭包
您还可以完全放弃使用命名函数,而是使用闭包形式的匿名函数,如下所示
use Asko\Router\Router; $router = new Router(); $router->get("/hello-world", function() { echo "Hello, World!"; }); $router->dispatch();
参数
路由器中的参数是命名的,然后在函数(或方法)声明中使用具有相同名称的参数。假设您有这个路由
$router->get("/hello/{who}", ...);
那么您需要引用的参数名称也是 $who
,如下所示
$router->get("/hello/{who}", function(string $who) { echo "Hello, {$who}!"; });
您可以拥有任意数量的参数,并且函数声明中它们的顺序无关紧要。唯一重要的是名称与路由参数匹配。
注意:您的参数必须显式指定为string
、int
或float
类型。未指定类型的参数将被假定为string
。
依赖注入
路由器以在函数(或方法)声明中对类进行类型提示的形式提供无需配置的依赖注入。依赖注入必须在路由参数之前发生。一个示例注入如下
use Asko\Router\Router; class SomeDependency {} $router = new Router(); $router->get("/hello/{who}", function(SomeDependency $dep, string $who) { echo "Hello, {$who}"; }); $router->dispatch();
上述示例实例化了SomeDependency
类并将其注入到可调用项中。所有可调用项类型都受支持:控制器方法(以及构造函数方法!)函数和闭包。
所有注入都具有递归性质,这意味着注入的类也可以通过在其各自的构造函数方法中对注入进行类型提示来受益于无需配置的依赖注入。
中间件
中间件是在实际路由分发之前运行代码的一种方式。您可以使用中间件检查用户是否已认证,或者用户是否有权访问路由等。您可以通过使用middleware
方法将中间件添加到路由器中,如下所示
use Asko\Router\Router; class SomeMiddleware { public function handle(string $who): string { return "intercepted, {$who}!"; } } $router = new Router(); $router->get( path: '/hello/{who}', callable: fn(string $who) => "Hello, {$who}!", middlewares: [SomeMiddleware::class] });
当上述路由被分发时,将实例化SomeMiddleware
类并调用其handle
方法。如果handle
方法返回任何非null
值,则不会分发路由,而是返回handle
方法的返回值。
中间件的handle
方法也完全支持依赖注入,并可以使用与路由本身相同的参数。