eru123 / router
使用父子模型的PHP库,用于处理路由
v1.0.2
2023-11-20 03:46 UTC
README
PHP库,用于处理HTTP请求。
有关最新文档,请访问 文档
支持的功能
-
URL参数
- 允许在URL路径中允许动态参数(例如:/user/$id
) -
静态路由
- 从目录中提供静态文件(即使是禁止的目录)并具有目录遍历保护 -
回退路由
- 处理不匹配任何其他路由但匹配前缀URL的请求的路由 -
调试
- 调试模式,用于调试路由和路由状态 -
路由状态
- 路由状态传递给所有路由处理程序和响应处理程序 -
路由引导程序
- 允许您运行预处理程序,并允许您在路由器开始运行处理程序之前操作路由状态 -
路由处理程序
- 当路由匹配请求时调用路由处理程序 -
响应处理程序
- 在最后一个路由处理程序调用后调用响应处理程序 -
错误处理程序
- 当路由处理程序创建可抛出对象时调用错误处理程序 -
父子路由
- 您可以创建父子路由以分组路由
基本用法
安装
composer require eru123/router
创建基本路由
<?php require_once __DIR__ . '/vendor/autoload.php'; use eru123\router\Router; use eru123\router\Builtin; // Create Router instance $r = new Router; // Enable Debug Mode. // When debug mode is on, we add is_debug and debug() methods to the route state // $state->is_debug - true if debug mode is on // $state->debug - array of debugging information (ex: routes, route, errors, etc.) $r->debug(); // Base Path // This is used as the prefix for all routes $r->base('/api'); // Set a response handler using a callable function // Response handlers are called after the last route // handler is called, it uses the return value of the // last route handler as the first argument and then // the route state as the second argument $r->response(function($result, $state) { if (is_array($res) || is_object($res)) { header('Content-Type: application/json'); if ($state->is_debug && is_array($res)) { $result['debug'] = $state->debug; } print json_encode($result); exit; } if (is_string($result) && strpos($result, '<?xml') === 0) { header('Content-Type: application/xml'); print $result; exit; } print $result; exit; }); // Set an error handler using a callable function // Error handlers are called when a route handler creates a Throwable $r->error(function($error, $state) { $result = [ 'error' => $error->getMessage(), 'code' => $error->getCode(), ]; if ($state->is_debug) { $result['debug'] = $state->debug; } header('Content-Type: application/json'); print json_encode($result); exit; }); // Default response and error handlers $r->response([Builtin::class, 'response']); $r->error([Builtin::class, 'error']); // Create Route Request // The first argument is the HTTP method // The second argument is the path // The third and so on arguments are route handlers $r->request('GET', '/', function($state) { return 'Hello World!'; }); // Request Aliases // We implement most used and common HTTP methods as aliases $r->get($path, $handler); $r->post($path, $handler); $r->put($path, $handler); // URL Parameters // You can use URL parameters in the path with $<name> syntax. // Parameter name must start with alpha and the following // characters can be alpanumeric or underscore. $r->get('/user/$id', function($state) { return 'User ID: ' . $state->params['id']; }); // Fallback Route // This route is called when no other route matches // all requests with /pages as the base path will // be handled by this route if no other route matches $r->fallback('/pages', function($state) { return 'Page not found'; }); // OR Global Fallback Route // This route is called when no other route matches // all requests will be handled by this route if no other route matches. // It uses a prefix url, and process the fallback route only if the URL // matches the prefix url. // Example: // $r->fallback('/pages', $handler) // Process all requests starting with /pages (ex: /pages/1, /pages/user/1, etc.) $r->fallback('/', function($state) { return 'Page not found'; }); // Static Routes // Static routes are routes that are intended to be used for static files. // It can serve files from a forbidden directory that can't be accessed by // the client. You can inject a middleware to it for checking authentication // or etc. // It uses a prefix url, and process the static route only if the URL // matches the prefix url. // For the second argument, you need to pass a directory path where the // request file needs to be looked up. // Example: // $r->static('/css', __DIR__ . '/../src/assets/css', $handler) // Process all requests starting with /css (ex: /css/style.css, /css/style.min.css, etc.) $r->static('/static', __DIR__ . '/static', function($state) { // Check if user is authenticated if (!$state->user) { throw new \Exception('Not authenticated', 401); // this will be handled by the error handler // You can also return a response here if you dont want to use the error handler header('Content-Type: application/json'); print json_encode([ 'error' => 'Not authenticated', 'code' => 401, ]); exit; } // If the handler doesn't return anything, the file will be served accordingly });
高级用法
在本节中,我们将介绍一些高级用法以及有关库使用的深入细节。
路由器路径匹配顺序
对于高级用法,您需要了解路由器如何将请求路径匹配到路由路径。路由器按照以下顺序将请求路径匹配到路由路径:
Router::static('/', $directory[, ...$handlers])
- 使用静态方法定义的路由首先匹配。Router::request($method, $path, ...$handlers)
、Router::get($path, ...$handlers)
、Router::post($path, ...$handlers)
- 使用请求方法及其别名定义的路由接下来匹配。Router::fallback($path, ...$handlers)
- 使用回退方法定义的路由最后匹配。
关于这些组内的匹配顺序,路由器按先来先服务的顺序将请求路径匹配到路由路径。
例如,如果您有以下路由
// First come first serve order // this will be matched first, this will also match /user/me $r->get('/user/$x', $handler1); // this will be matched second, but it's handlers will not be // called unless the $handler1's state called skip() method // Example: $state->skip(); $r->get('/user/me', $handler2); // NOTE: These kind of URL path designs are NOT RECOMMENDED.
路由状态
RouteState
是传递给所有处理程序以在处理程序和路由之间共享信息的类实例。
以下是您可以使用的 RouteState
方法
skip()
- 将状态设置为允许跳过以跳过当前路由的所有剩余处理程序,以转到下一个路由。unskip()
- 将状态设置为不允许跳过以取消跳过状态。is_allowed_skip()
- 检查状态是否允许跳过。值可以是true
、false
或null
。null
表示状态未设置或未调用skip()
或unskip()
。next()
- 必须为每个路由处理程序调用此方法(除了最后一个处理程序),以转到下一个处理程序。stop()
- 如果您想停止当前路由的下一个处理程序的执行,则应调用此方法。is_allowed_next()
- 检查状态是否允许转到下一个处理程序。值可以是true
、false
或null
。null
表示状态未设置或未调用next()
或stop()
。extract_info(Route $route)
- 从 $route->info() 的结果中提取信息,并将其设置为 RouteState 属性。以下是定义要提取的路由信息属性method
- 路由中定义的 HTTP 方法。这还包括此库的魔法方法,如 ANY、FALLBACK 和 STATIC。path
- 路由中定义的 URL 路径。如果您在路由器中设置了基本路径,它将包含在路径中。params
- 路由中定义的 URL 参数数组。matched
- 一个布尔值,表示路由是否与请求路径匹配。regex
- 用于将请求路径与路由路径匹配的正则表达式模式。
或者,您可以通过直接设置来覆盖 RouteState
属性,就像使用魔法一样。例如
// Override existing properties $state->method = 'GET'; $state->path = '/user/1'; // Add new properties $state->user_id = 1;
但是,有一些受保护的属性您无法覆盖,它们是
allow_next
allow_skip
route
静态处理器 Router::static($path, $directory[, ...$handlers])
$path
- 静态路由的 URL 路径前缀。$directory
- 请求文件需要查找的目录路径。$handlers
- 可选的路由处理器。这些可以是任何可调用的函数、类静态方法或对象方法调用,它接受一个参数为RouterState $state
对象。
从禁止的目录中提供文件服务
静态处理器可以提供由网络服务器配置(例如 Apache 的 deny from all
指令)禁止访问的目录中的文件。只要网络服务器应用程序的系统用户可以访问该目录,静态处理器就可以提供文件。
$r->static('/', '/');