FastRoute Test Demo With PHP
Website:Fast request router for PHP
PregRoute.class
`
<?php
class PregRoute
{
const NOT_FOUND = 404;
const FOUND = 200;
/** ~^/user/([^/]+)/(\d+)$~
* ~^/user/(\d+)$~
* ~^/user/([^/]+)$~
* @var string 单个正则
*/
protected $single_regex = '~^/user/([^/]+)/(\d+)$~';
/** 基于位置匹配
* @var string 多个路由匹配规则
*/
protected $combined_position_regex = "
~^(?:
/user/([^/]+)/(\d+)
| /user/(\d+)
| /user/([^/]+)
)$~x";
/** 位置匹配数据
* @var array
*/
protected $route_data_position = [
1 => ['handler0', ['name', 'id']], # /user/tom/1 regex=> /user/([^/]+)/(\d+)
3 => ['handler1', ['id']], # /user/1 regex=> /user/(\d+)
4 => ['handler2', ['name']], # /user/tom regex=> /user/([^/]+)
];
/** 基于计数匹配
* @var string 多个路由匹配规则
*/
protected $combined_count_regex = "
~^(?|
/user/([^/]+)/(\d+)
| /user/(\d+)()()
| /user/([^/]+)()()()
)$~x";
/** 基于计数匹配,只修改 ?:
* @result 将 ?: 换成 ?| 可以组号重置,但
* | /user/(\d+)
* | /user/([^/]+) 的count都相同,采用()进行个数填充,也可以使用其它方式,如
* <result1>/user/(\d+)
* <result2>/user/([^/]+)
* @var string
*/
protected $combined_count_regex2 = "
~^(?|
/user/([^/]+)/(\d+)
| /user/(\d+)
| /user/([^/]+)
)$~x";
/** 计数匹配数据
* @var array
*/
protected $route_data_count = [
3 => ['handler0', ['name', 'id']], # /user/tom/1 regex=> /user/([^/]+)/(\d+)
4 => ['handler1', ['id']], # /user/1 regex=> /user/(\d+)
5 => ['handler2', ['name']], # /user/tom regex=> /user/([^/]+)
];
/** 块正则表达式
* @var array
*/
protected $combined_count_regexes = [];
/** 块正则表达式数据
* @var array
*/
protected $route_data_counts = [];
/** 基于位置调度路由
* @param $url
* @way 基于组位置的非分块
* @result 单个占位符的情况下提供了相当好的性能
* 占位符过多,在最坏的情况下(最后一条路线匹配),性能下降到比普通方法慢两倍以上的程度
* @return array
*/
public function dispatchPosition($url)
{
if(!preg_match($this->combined_position_regex,$url,$matches)) {
return [self::NOT_FOUND];
}
//$i找到第一个非空偏移量并查找了相关数据后
//可以通过继续遍历$matches数组并将值与变量名配对来填充占位符变量。
for($i = 1; '' === $matches[$i]; ++$i);
list($handler, $varNames) = $this->route_data_position[$i];
$vars = [];
foreach ($varNames as $varName) {
$vars[$varName] = $matches[$i++];
}
return [self::FOUND, $handler, $vars];
}
//++++++++++++++++++++++++++++++++++++++++
// 组号重置:
// PCRE regex 语法:
// (?| ... )是非捕获组类型。
// (?:和之间的区别在于 ,(?|后者将重置其包含的每个分支中的组号
//++++++++++++++++++++++++++++++++++++++++
/** 基于计数调度路由
* @param $url
* @return array
*/
public function dispatchCount($url)
{
if(!preg_match($this->combined_count_regex,$url,$matches)) {
return [self::NOT_FOUND];
}
list($handler, $varNames) = $this->route_data_count[count($matches)];
$vars = [];
$i = 0;
foreach ($varNames as $varName) {
$vars[$varName] = $matches[++$i];
}
return [self::FOUND, $handler, $vars];
}
/** 基于计数调度路由,非()占位
* @param $url
* @return array
*/
public function dispatchCount2($url)
{
if(!preg_match($this->combined_count_regex2,$url,$matches)) {
return [self::NOT_FOUND];
}
var_dump($matches);
}
/** 块正则表达式调度
* @param $url
* @return array
*/
public function dispatchBlock($url)
{
foreach ($this->combined_count_regexes as $i => $regex) {
if (!preg_match($regex, $url, $matches)) {
continue;
}
list($handler, $varNames) = $this->route_data_counts[$i][count($matches)];
$vars = [];
$i = 0;
foreach ($varNames as $varName) {
$vars[$varName] = $matches[++$i];
}
return [self::FOUND, $handler, $vars];
}
}
//+++++++++++++++++++++++++++++++++++++++++
//组合的正则表达式方法对于少量的正则表达式非常有效,
//但是如果涉及许多正则表达式则不是最佳选择,而如果每个规则有多个捕获组则则是灾难性的。
//通过仅组合大约十个表达式的块可以提高性能。
//这不仅可以总体上提高性能,而且可以解决多组情况下性能特别差的问题。
//一旦开始使用分块,基于组计数的替代方法就不会有太大的区别。
//捕获组较少时,情况稍差一些,而许多组则稍好一些。特别是对于路由,通常每条路由涉及多个占位符,基于组计数的方法似乎更可取。
//另一方面,对于词法分析,每个标记通常仅使用一个捕获组,因此基于位置的方法将获胜。
//+++++++++++++++++++++++++++++++++++++++++
}
$testClass = new PregRoute();
$url = '/user/tom'; #/user/1 | /user/tom/1
$dispatchPosition = $testClass->dispatchPosition($url);
$dispatchCount = $testClass->dispatchCount($url);
var_dump($dispatchPosition);
var_dump($dispatchCount);
`
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。