henriquebs0 / router
Requires
- php: >=8.0.12
This package is auto-updated.
Last update: 2024-09-28 21:59:56 UTC
README
PHP 组件,用于控制您的应用程序的路由。
PHP 组件,用于控制您应用程序的路由。
安装
Composer
composer require henriquebs0/router dev-main
路由
要开始管理路由,只需在应用程序中所有请求都经过的中心点(例如,文件 index.php)处实例化 Router(string $baseUri = '/')
类的对象,添加路由,然后调用 resolve()
方法。
htaccess
RewriteEngine On
# ROUTER URL Rewrite
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
index.php
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Router; /** * Instantiating the object */ $router = new Router(); /** * Adding a route to the '/' path */ $router->get('/', function() { echo 'Hello World!'; }); /** * Resolves the process and forwards to the route */ $router->resolve();
添加路由
添加路由有五种方法,这些方法直接与 HTTP 方法相关,分别是
-
get($path, $callback, $middlewaresClasses): void
-
post($path, $callback, $middlewaresClasses): void
-
put($path, $callback, $middlewaresClasses): void
-
patch($path, $callback, $middlewaresClasses): void
-
delete($path, $callback, $middlewaresClasses): void
string $path
: 将被访问的路径。callable|array $callback
: 要执行的功能。array $middlewaresClasses
: 中间件类。
<form method="POST"> <label for="_method">Method</label> <select name="_method" id="_method"> <option value="GET">GET</option> <option value="POST">POST</option> <option value="PUT">PUT</option> <option value="PATCH">PATCH</option> <option value="DELETE">DELETE</option> </select> <input type="submit" value="Send"> </form> <?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Router; class Controller { public function get() { echo "GET"; } public function post() { echo "POST"; } public function put() { echo "PUT"; } public function patch() { echo "PATCH"; } public function delete() { echo "DELETE"; } } $router = new Router(); $router->get('/', [Controller::class, 'get']); $router->post('/', [Controller::class, 'post']); $router->put('/', [Controller::class, 'put']); $router->patch('/', [Controller::class, 'patch']); $router->delete('/', [Controller::class, 'delete']); $router->resolve();
注意,存在一个保留参数 _method
,这是因为 HTML5 表单仅支持 GET
和 POST
方法。
URL 参数
要告知期望参数,请将此参数的名称放在花括号内,这些将被按顺序传递给路由回调。
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Router; class Controller { public function user($id) { echo "User id - {$id}"; } } $router = new Router(); /** * Expect to receive the 'id' parameter */ $router->get('/user/{id}', [Controller::class, 'user']); $router->resolve();
分组
为了简化告知路径的过程,存在一个 group(string $group)
方法,该方法为所有后续告知的路由设置基本路径。就像前面的例子使用这个功能。
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Router; class Controller { public function user($id) { echo "User id - {$id}"; } } $router = new Router(); $router->group('/user'); $router->get('/{id}', [Controller::class, 'user']); $router->resolve();
未找到
当访问的 URL 与任何路由不匹配时,会触发默认方法,它将请求状态设置为 404,然后打印此值。要更改此行为,可以使用 setNotFound(callable|array $callback)
方法。
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Router; $router = new Router(); $router->setNotFound(function() { echo 'Not Found.'; }); $router->resolve();
中间件
中间件是一种检查到达您应用程序的请求的方式。要创建中间件,只需创建一个扩展 Middleware
的类。
<?php use HenriqueBS0\Router\Middleware; class MiddlewareExample extends Middleware { public function checks(): bool { return true; } public function invalidated(): void { echo 'Not authorized'; } }
上述类由两个方法组成,checks()
用于检查请求是否授权,以及 invalidated()
,当请求未授权时(当 checks()
返回 false
)执行。
关联中间件
中间件可以直接与路由关联,也可以以一般方式关联。在以一般方式添加中间件后,所有后续添加的路由都将考虑它。
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Middleware; use HenriqueBS0\Router\Router; class MiddlwareGeneralOne extends Middleware {} class MiddlwareGeneralTwo extends Middleware {} class MiddlwareRouteOne extends Middleware {} class MiddlwareRouteTwo extends Middleware {} $router = new Router(); /** * Linking middleware in general * All routes added after this action will consider middlewares * 'MiddlwareGeneralOne' and 'MiddlwareGeneralTwo' */ $router->setMiddlewares([ MiddlwareGeneralOne::class, MiddlwareGeneralTwo::class ]); /** * Binding middleware specifically to route */ $router->get('/', function() { echo 'Hello World'; }, [MiddlwareRouteOne::class, MiddlwareRouteTwo::class]); $router->resolve();
处理关联中间件的一般方法
setMiddlewares(array $middlewaresClasses): void
addMiddleware(string $middlewareClass): void
clearMiddlewares(): void
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Middleware; use HenriqueBS0\Router\Router; class MiddlwareOne extends Middleware {} class MiddlwareTwo extends Middleware {} class MiddlwareThree extends Middleware {} class MiddlwareFour extends Middleware {} $router = new Router(); /** * Define that the middlewares applied will be * 'MiddlwareOne' and 'MiddlwareTwo' */ $router->setMiddlewares([ MiddlwareOne::class, MiddlwareTwo::class ]); /** * Clear all general middleware, * ie no middleware will be applied */ $router->clearMiddlewares(); /** * Add general middleware 'MiddlwareThree' and 'MiddlwareFour' */ $router->addMiddleware(MiddlwareThree::class); $router->addMiddleware(MiddlwareFour::class); /** * According to flow the 'MiddlwareThree' and 'MiddlwareFour' * middleware will be linked to the route */ $router->get('/', function() { echo 'Hello World'; }); $router->resolve();
路由分组
为了使代码更加组织化,可以将路由分离到类中,然后使用 addRoutesGroup(string $routesGroupClass)
方法将这些路由分组添加到 Router
类的实例中。这些路由分组类必须扩展 RoutesGroup
类。
<?php require_once __DIR__ . '/vendor/autoload.php'; use HenriqueBS0\Router\Middleware; use HenriqueBS0\Router\Router; use HenriqueBS0\Router\RoutesGroup; class MiddlewareGeneral extends Middleware {}; class MiddlewareRoutesUser extends Middleware{}; class ControllerUser { public function userGet($id) { echo "User - {$id} | GET"; } public function userPost() { echo 'User | POST'; } public function userPut($id) { echo "User - {$id} | PUT"; } public function userPatch($id) { echo "User - {$id} | PATCH"; } public function userDelete($id) { echo "User - {$id} | DELETE"; } } /** * Class with route group */ class RoutesUser extends RoutesGroup { /** * Reserved method for adding routes */ protected function setRoutes(): void { $this->group('/user'); $this->setMiddlewares([MiddlewareRoutesUser::class]); $this->get('/{id}', [ControllerUser::class, 'userGet']); $this->post('/', [ControllerUser::class, 'userPost']); $this->put('/{id}', [ControllerUser::class, 'userPut']); $this->patch('/{id}', [ControllerUser::class, 'userPatch']); $this->delete('/{id}', [ControllerUser::class, 'userDelete']); } } $router = new Router(); $router->get('/', function() { echo 'Hello World!'; }); /** * Adding general middleware */ $router->addMiddleware(MiddlewareGeneral::class); /** * Adding a generic group */ $router->group('/generic'); /** * Adding route group */ $router->addRoutesGroup(RoutesUser::class); $router->resolve();
请注意,扩展 RoutesGroup
的类有保留方法 setRoutes()
,其中必须定义路由。与 RoutesGroup
类具有相同目的的方法,它们是
get($path, $callback, $middlewaresClasses): void
post($path, $callback, $middlewaresClasses): void
put($path, $callback, $middlewaresClasses): void
patch($path, $callback, $middlewaresClasses): void
delete($path, $callback, $middlewaresClasses): void
group(string $group): void
setMiddlewares(array $middlewaresClasses): void
addMiddleware(string $middlewareClass): void
clearMiddlewares(): void
与路由分组关联的外部通用中间件,如示例
MiddlewareGeneral
。
在
setRoutes
方法的作用域内,group
方法不会干扰Router
类实例的group
方法,反之亦然。
示例项目: Link Pack