lloydzhou / router
Requires
- php: >=5.3.0
Requires (Dev)
README
PHP的简单路由器。
匹配URL并执行PHP函数。
根据处理器函数参数列表自动获取变量。
支持将路由器回调处理器编译成纯数组源代码。
中文版.
安装
composer require bephp/router
API参考
group/prefix($prefix, $hook)
添加具有相同前缀的组路由器。如果不传递参数$prefix,则将路由器实例的$prefix属性重置为空字符串。将$hook合并到该组中。
match($method, $path, $callback, $hook)
根据给定的$method和$path创建路由树,将$callback和$hook存储在叶节点中。
get/post/put/delete/head/options($path, $callback, $hook)
包装没有$method参数的match方法。还定义了"post"、"put"、"delete"、"head"等。
execute()
应用程序的入口点。有3个可选参数,$params将与请求变量合并并传递给回调处理器。在不作为Web服务器部署时,可以传递$method和$path来测试此库。
error()
- 如果使用$error_code和$callback调用此API,只需为错误代码定义回调处理器。
- 如果使用$error_code和其他参数调用此API,将触发错误回调处理器,参数将传递给错误处理器。
hook()
- 如果使用$hook_name和$callback调用此API,只需为钩子名称定义回调处理器。
- 如果使用$hook_name和其他参数调用此API,将触发钩子处理器,参数将传递给钩子处理器。
- 有2个特殊钩子:"before"和"after",此库将在执行处理器之前自动调用"before"钩子,并在执行处理器之后调用"after"钩子。
- "after"钩子将自动触发回调处理器的返回值。
- "before"钩子和其他用户定义的钩子将自动触发当前路由对象$router和存储在$router->params中的合并参数。如果这些钩子返回false,将触发406错误处理器。
验证
使用ctype函数在pathinfo中验证参数
示例
如果定义了路由器:"/hello/:name:a.json",并使用URL:"/hello/lloyd.json"解析URL。
将调用函数"ctype_alpha"来验证"lloyd"。
验证命令将ctype函数映射
A => ctype_alnum
a => ctype_alpha
d => ctype_digit
x => ctype_xdigit
l => ctype_lower
u => ctype_upper
编译
PHP请求总是匹配回调处理程序。但是请求只匹配一个回调。因此,我们可以将路由树节点编译成普通数组,以节省时间。
开发模型
使用CRouter而不是Router,将始终编译源代码为目标文件。
$crouter = new CRouter("router.inc.php", true);
生产模型
仅包含目标源代码,并使用参数执行它。
$router = include("router.inc.php");
$router->execute();
性能
- 使用树结构在叶节点上存储回调处理程序。确保查找回调函数的时间复杂度为O(log n)。
- 使用CRouter类,支持将路由回调处理程序编译成普通数组源代码。因此可以节省时间,通过分割路径信息来创建存储回调的树节点。
基准测试
使用"php-router-benchmark"测试路由性能。
最坏情况匹配
此基准测试匹配最后一个路由和未知路由。它生成随机前缀和后缀的路由,以试图阻止任何优化。1,000个路由,每个路由有9个参数。
此基准测试由10个测试组成。每个测试执行1,000次,结果剪枝,然后取平均值。超出平均值3个标准差的值将被丢弃。
测试名称 | 结果 | 时间 | + 间隔 | 变化 |
---|---|---|---|---|
路由器 - 未知路由(1000个路由) | 993 | 0.0000232719 | +0.0000000000 | 基准线 |
路由器 - 最后一个路由(1000个路由) | 981 | 0.0000955424 | +0.0000722705 | 慢311% |
FastRoute - 未知路由(1000个路由) | 990 | 0.0005051955 | +0.0004819236 | 慢2071% |
FastRoute - 最后一个路由(1000个路由) | 998 | 0.0005567203 | +0.0005334484 | 慢2292% |
Symfony2 Dumped - 未知路由(1000个路由) | 998 | 0.0006116139 | +0.0005883420 | 慢2528% |
Symfony2 Dumped - 最后一个路由(1000个路由) | 998 | 0.0007765370 | +0.0007532651 | 慢3237% |
Symfony2 - 未知路由(1000个路由) | 996 | 0.0028456177 | +0.0028223458 | 慢12128% |
Symfony2 - 最后一个路由(1000个路由) | 993 | 0.0030129542 | +0.0029896823 | 慢12847% |
Aura v2 - 最后一个路由(1000个路由) | 989 | 0.1707107230 | +0.1706874511 | 慢733450% |
Aura v2 - 未知路由(1000个路由) | 988 | 0.1798588730 | +0.1798356011 | 慢772760% |
示例
belong是一个简单的示例,请参阅example.php中的完整示例。
(new Router())
->error(405, function($message){
header('Location: /hello/world', true, 302);
})
->get('/hello/:name', function($name){
echo "Hello $name !!!";
})
启动服务器
php -S 0.0.0.0:8888 example.php
测试
URL不匹配,触发405错误处理程序。
curl -vvv 127.0.0.1:8888
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8888
> Accept: */*
>
< HTTP/1.1 302 Found
< Host: 127.0.0.1:8888
< Connection: close
< X-Powered-By: PHP/5.5.9-1ubuntu4.12
< Location: /hello/world
< Content-type: text/html
<
* Closing connection 0
URL匹配获取当前结果。
curl -vvv 127.0.0.1:8888/hello/lloyd
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> GET /hello/lloyd HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8888
> Accept: */*
>
< HTTP/1.1 200 OK
< Host: 127.0.0.1:8888
< Connection: close
< X-Powered-By: PHP/5.5.9-1ubuntu4.12
< Content-type: text/html
<
* Closing connection 0
Hello lloyd !!!
演示
有一个博客演示,与ActiveRecord和MicroTpl一起工作。