gac / routing
自定义路由库,特别适用于快速API开发
v3.1.7
2024-08-22 19:15 UTC
Requires
- php: >=8.0
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- pestphp/pest: ^1.21
This package is auto-updated.
Last update: 2024-09-22 19:32:44 UTC
README
这个库允许您创建静态或动态路由。这个库受到了 PHP Slim 框架 的启发
通过 composer 安装
composer require gac/routing
手动安装
从 发布页面 下载最新版本。
别忘了将以下 include_once
语句添加到您的 php 文件中
include_once "./Exceptions/CallbackNotFound.php"; include_once "./Exceptions/RouteNotFoundException.php"; include_once "./Request.php"; include_once "./Routes.php";
安装后
为了正确使用这个库,您需要在项目的根目录下创建一个 .htaccess
文件。
.htaccess
文件的示例可能如下所示
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)$ index.php [QSA,L]
注意
如果您将主文件重命名了,请将 .htaccess
文件中的 index.php
替换为您的主应用文件。
快速开始
示例代码,帮助您快速开始开发。
use Gac\Routing\Exceptions\CallbackNotFound; use Gac\Routing\Exceptions\RouteNotFoundException; use Gac\Routing\Request; use Gac\Routing\Response; use Gac\Routing\Routes; include_once "vendor/autoload.php"; # IF YOU'RE USING composer $routes = new Routes(); try { $routes->add('/', function (Request $request) { // Old way of doing it, still supported until v4 $request ->status(200, "OK") ->send(["message" => "Welcome"]); // New way of doing it Response:: withHeader("Content-Type", "application/json"):: withStatus(200, 'OK'):: withBody([ "message" => "Welcome" ]):: send(); }); $routes->route('/', function (Request $request) { // Old way of doing it, still supported until v4 $request ->status(200, "OK") ->send(["message" => "Welcome"]); // New way of doing it Response:: withHeader("Content-Type", "application/json"):: withStatus(200, 'OK'):: withBody([ "message" => "Welcome" ]):: send(); }, [Routes::POST])->save(); $routes->route(); } catch (RouteNotFoundException $ex) { // Old way of doing it, still supported until v4 $routes->request->status(404, "Route not found")->send(["error" => ["message" => $ex->getMessage()]]); // New way of doing it Response::withStatus(404, 'Route not found')::send(["error" => [ "message" => $ex->getMessage() ]]); } catch (CallbackNotFound $ex) { // Old way of doing it, still supported until v4 $routes->request->status(404, "Callback not found")->send(["error" => ["message" => $ex->getMessage()]]); // New way of doing it Response::withStatus(404, 'Callback not found')::send(["error" => [ "message" => $ex->getMessage() ]]); } catch (Exception $ex) { $code = $ex->getCode() ?? 500; // Old way of doing it, still supported until v4 $routes->request->status($code)->send(["error" => ["message" => $ex->getMessage()]]); // New way of doing it Response::withStatus($code)::send(["error" => [ "message" => $ex->getMessage() ]]); }
示例
动态路由示例
$routes->add('/test/{int:userID}-{username}/{float:amount}/{bool:valid}', function ( Request $request, int $userID, string $username, float $amount, bool $valid ) { echo 'Dynamic route content here'; });
链式路由
在使用链式方法时,最后一个方法可以使用 ->save()
或 ->add()
来表示链的结束
注意
->save(true|false)
方法仍然可以链式使用- 将
false
(默认值是true
)传递给->save()
方法将保留该链中所有前面的前缀和中间件
- 将
->add()
不能 链式使用,应该是链的最后一个调用
$routes ->prefix('/user') // all the routes added will have the /user prefix ->middleware([ 'verify_token' ]) // all the routes added will have the verify_token middleware applied ->route('/', [ HomeController::class, 'getUsers' ], Routes::GET) ->route('/', [ HomeController::class, 'addUser' ], Routes::POST) ->route('/', [ HomeController::class, 'updateUser' ], Routes::PATCH) ->route('/', [ HomeController::class, 'replaceUser' ], Routes::PUT) ->add('/test', [ HomeController::class, 'deleteUser' ], Routes::DELETE);
链式路由,以 save 结束
$routes ->prefix("/test") ->middleware(['decode_token']) ->route("/t0", function(Request $request){}) ->get("/t1", function (){}) ->post("/t2", function (){}) ->put("/t3", function (){}) ->patch("/t4", function (){}) ->delete("/t5", function (){}) ->save();
链式路由,在一个调用中包含多个链
$routes ->prefix("/test") ->middleware([ 'decode_token' ]) ->get("/t1", function () { }) // route would be: /test/t1 ->get("/t2", function () { }) // route would be: /test/t2 ->get("/t3", function () { }) // route would be: /test/t3 ->save(false) // by passing the false argument here, we keep all the previous shared data from the chain (previous prefix(es) and middlewares) ->prefix("/test2") ->middleware([ "verify_token" ]) ->get("/t4", function () { }) // route would be: /test/test2/t4 ->get("/t5", function () { }) // route would be: /test/test2/t5 ->get("/t6", function () { }) // route would be: /test/test2/t6 ->save() // by not passing the false argument here, we are removing all shared data from the previous chains (previous prefix(es) and middlewares) ->prefix("/test3") ->middleware([ "verify_token" ]) ->get("/t7", function () { }) // route would be: /test3/t7 ->get("/t8", function () { }) // route would be: /test3/t8 ->get("/t9", function () { }) // route would be: /test3/t9 ->add(); //using save or add at the end makes the chaining stop and allows for other independent routes to be added
传递参数到中间件方法
当与中间件一起工作时,如果需要,您也可以传递它们参数
use Gac\Routing\Response; $routes ->middleware([ 'test_middleware', 'has_roles' => 'admin,user', [ Middleware::class, 'test_method' ], [ Middleware::class, 'has_role', 'Admin', 'Moderator', [ 'User', 'Bot' ] ], ]) ->add('/test', function (Request $request) { // Old way of doing it, still supported until v4 $request->send([ 'msg' => 'testing' ]); //New way of doing it Response::send([ "msg" => "testing" ]); });
只要指定了正确的类型,每个中间件函数也可以在任何位置接受类型为 Gac\Routing\Request
的参数。
可选参数
$routes->add( '/demo/{id?}', function($id = 'defaultValue'){ echo "ID: . $id"; }, Routes::GET );
当使用 /demo
调用此端点时,它将输出 ID: defaultValue
,而使用 /demo/123
时将输出 ID: 123
在路由类上使用依赖注入
当使用类来处理您的路由回调,并且这些类有一些需要通过构造函数注入的依赖时,您可以指定要注入的参数数组,或者让库尝试自动注入类。
$routes->add( '/demo', [ HomeController::class, 'dependency_injection_test', [ new InjectedClass() ] ], Routes::GET );
您还可以使用命名参数或混合使用它们
$routes->add( '/demo', [ HomeController::class, 'dependency_injection_test', [ "injected_var" => new InjectedClass(), new Middleware ] ], Routes::GET );
让库自动注入类到构造函数中
$routes->add( '/demo', [ InjectController::class ], Routes::GET );
注意
如果没有提供任何类,库将始终尝试自动注入类(将跳过默认值为 null 的类),如果您使用类作为回调。
对于单方法类,请使用 __invoke
$routes->add( '/invoke', [ HomeController::class ], Routes::GET );
您还可以使用 __invoke
进行依赖注入
$routes->add( '/invoke', [ HomeController::class, [ new InjectedClass() ] ], Routes::GET );
更多示例请查看 sample 文件夹 中的 index.php
文件
文档
源代码文档可以在 PHP Routing 文档 页面找到
特性
- 静态路由
- 动态路由
- 动态路由与可选参数
- 中间件
- 向中间件传递参数
- 路由前缀
- 方法链式调用
- 类上的依赖注入
- 手动注入
- 自动注入