grogorick / php-routing
零依赖的最小PHP路由
README
以简单的关联数组结构设置分层路由的回调。
设置
composer require grogorick/php-routing
示例
# api.php require_once 'vendor/autoload.php'; use Grogorick\PhpRouting as R; ... function get_feed($GET_data) { $feed_data = ... if ($feed_data) R\respond($feed_data); else R\respond(null, R\Response::ERROR_NOT_FOUND); } ... R\route([ 'v1' => [ 'sign-in' => [ 'POST' => 'App\Auth\sign_in' ], '(authenticated)' => R\Check('App\Auth\verify_authorization_header', [ 'accounts' => R\Entity([ 'POST' => fn() => R\respond('create account'), 'GET' => fn() => R\respond('list accounts'), '/\w+/' => fn($account_slug) => R\Item([ 'GET' => fn() => R\respond('get account ' . $account_slug), 'PUT' => fn() => R\respond('replace account ' . $account_slug), 'PATCH' => fn() => R\respond('update account ' . $account_slug), 'DELETE' => fn() => R\respond('delete account ' . $account_slug) ]), ... ]), 'posts' => R\Entity([ /* post_id */ '/\d+/' => R\IntParam([ 'GET' => fn($post_id) => R\respond('get post ' . $post_id), ... ]), ... ]), 'feed' => [ 'GET' => fn($GET_data) => get_feed($GET_data), ... ], ... ]), ... ], ... ]);
路由数组语法
route-literal => [子路由数组]
静态 route literal 字符串 => 子路由数组
/regex/ => subroutes function
regex 匹配URL参数 => subroutes function 获取解析的参数,生成子路由数组
(subroutes group) => subroutes function
subroutes group 名称在括号内 => subroutes function 生成子路由数组
METHOD => callable
请求 METHOD 完整大写 => 调用此路由的 callable 动作
动作可调用将使用以下参数调用
URL参数 — 在相应路由中的顺序
表单数据 — 通过$_POST或file_get_contents('php://input')
搜索参数 — 通过$_GET
参考
route($routes)
主要函数,用于解析当前请求URL并调用相应的回调函数。
$routes (关联数组)
— 路由字符串 literal => 子路由数组
— 路由参数正则表达式 => 闭包,解析参数作为参数,返回子路由数组
— 请求方法(POST/GET/PUT/PATCH/DELETE)=> 回调函数
respond($response, $code = 200)
辅助函数,以JSON编码的字符串输出检索到的响应,并设置可选的状态码。之后停止执行。
$response (任何) — 可序列化为JSON的响应对象
$code (int) — HTTP响应状态码
Check($check, $subroutes)
子路由数组的包装器,具有受限访问权限。
$check (callable) — 用于检查访问权限的回调函数
$subroutes — 参见 route($routes)
respond_error_if_no_other_route_matches($error)
在Check(...)中报告错误,而不直接停止路由。
$error (string) — 错误消息
Param($convert, $subroutes)
子路由数组的包装器,用于转换解析的URL参数。
$convert (callable) — 用于转换最新参数的回调函数
$subroutes — 参见 route($routes)
IntParam($subroutes)Param('intval', $subroutes)的缩写
$subroutes — 参见 route($routes)
Entity($subroutes)
Item($subroutes)
子路由数组的包装器,用于生成未定义请求方法的推荐响应状态码。
$subroutes — 参见 route($routes)
set_response_headers($headers)
add_response_header($header)
替换/添加当使用 respond(...) 时自动应用的头部。
$headers (数组) — 要替换所有默认/先前设置的头部
$header (字符串) — 要添加的头部
set_options($options)
设置 \Options 中可用的选项。
$options (关联数组) — 要设置的选项,使用 \Options 中的值作为数组键
服务器配置
额外的请求方法
默认情况下,大多数Apache配置仅允许 GET 和 POST 请求。添加以下内容以允许进一步的方法(PUT, PATCH, DELETE, HEAD, OPTIONS)。
# .htaccess <Limit GET POST PUT PATCH DELETE HEAD OPTIONS> Require all granted </Limit> Header always set Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS"
为此,应该包含 httpd.conf
<VirtualHost ...> <Directory ...> ... AllowOverride All ...
响应头部
响应头部可以通过PHP设置,允许动态设置,例如,支持多个特定来源
R\set_response_headers([ "Access-Control-Allow-Origin: $approved_request_origin", 'Access-Control-Allow-Headers: content-type', 'Content-Type: application/json; charset=UTF-8' ]);
或通过 .htaccess 如果静态设置足够
Header always set Access-Control-Allow-Origin "https://your-app.domain" Header always set Access-Control-Allow-Headers "content-type" Header always set Content-Type "application/json; charset=UTF-8"
URL语法
简短
https://你的API域名/v1/accounts/42
# .htaccess <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /api.php/$1 [L,QSA] </IfModule>
中等
https://你的API域名/api.php/v1/accounts/42
(大多数系统上已预配置)
# httpd.conf <VirtualHost ...> ... AcceptPathInfo On ...
或
# .htaccess AcceptPathInfo On
长
https://你的API域名/api.php?request=/v1/accounts/42
(纯PHP)