bephp/router

PHP 的快速路由器。匹配 URL 并执行 PHP 函数。根据处理器函数参数列表自动获取 GET 变量。支持将路由回调处理器编译成纯数组源代码。

v1.1.0 2016-04-15 07:49 UTC

README

Build Status Coverage Status Latest Stable Version Total Downloads Latest Unstable Version License
PHP 的基础路由器。
它匹配 URL 并执行 PHP 函数。
根据处理器函数参数列表自动获取 GET 变量。
支持将路由回调处理器编译成纯数组源代码。

中文版.

安装

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()

  1. 如果使用 $error_code 和 $callback 调用此 API,则仅定义错误代码的回调处理器。
  2. 如果使用 $error_code 和其他参数调用此 API,将触发错误回调处理器,参数将传递给错误处理器。

hook()

  1. 如果使用 $hook_name 和 $callback 调用此 API,则仅定义钩子名称的回调处理器。
  2. 如果使用 $hook_name 和其他参数调用此 API,将触发钩子处理器,参数将传递给钩子处理器。
  3. 有两个特定钩子:"before" 和 "after",此库将在执行处理器之前自动调用 "before" 钩子,并在执行处理器之后调用 "after" 钩子。
  4. "after" 钩子将自动与回调处理器的返回值一起触发。
  5. "before" 钩子和其他用户定义的钩子将自动与当前路由对象 $router 和存储在 $router->params 中的合并参数一起触发。如果这些钩子返回 false,则触发 406 错误处理器。

验证

使用 ctype 函数 验证路径信息中的参数。
示例

如果定义了路由器: "/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();

性能

  1. 使用树结构在叶节点上存储回调处理器。确保查找回调函数的时间复杂度为O(log n)。 树节点
  2. 使用CRouter类,支持将路由回调处理器编译成纯数组源代码。因此,可以通过拆分路径信息来节省创建树节点存储回调的时间。

基准测试

使用"php-router-benchmark"测试路由性能。

最坏情况匹配

此基准测试匹配最后一个路由和未知路由。它通过随机添加前缀和后缀来生成路由,以阻止任何优化。每个路由有9个参数,共1,000个路由。

此基准测试包括10次测试。每次测试执行1,000次,结果修剪后平均。超出平均数3个标准差的值将被丢弃。

示例

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 !!!

演示

有一个博客演示,与ActiveRecordMicroTpl一起工作。