robier / router
非常快且轻量级的PHP路由器
dev-master
2015-10-22 21:09 UTC
This package is auto-updated.
Last update: 2024-09-13 05:28:41 UTC
README
仍在开发中 :)
为了创建一个快速的路由系统,这个库被构建。它如此之快,以至于缓存会成为负担,结果也不会太好 :)
特性
- 快速匹配未知路由
- 匹配第一个和最后一个路由的时间几乎相同
- 路由可以无名称
- 支持多个域名且速度不受影响
- 支持HTTP方法(GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS)
- 从指定的路由名称反向生成URL并进行参数检查
- 编写URL定义的特殊语法
- 两种类型的模式(固定和组合)
- 常用模式的简短代码
- 注册自己的常用模式
安装
此项目需要PHP 5.5或更高版本。通过Composer安装此库非常简单,只需运行命令
composer require robier/router
如何使用
为了使一切正常运行,您需要设置Pattern
和Parser
对象,因为它们是Domain
集合的依赖项。设置好后,您可以注册您的路由。
$pattern = new Pattern(); $pattern->register('urlAlias', '[a-zA-Z0-9-\.äÄöÖüÜß]+', true); $parser = new Parser($pattern); $collection = new Domain('localhost.loc', $parser); $collection->add(Route::get('/[foo]')); $collection->add(Route::get('/contact')); $collection->add(Route::get('/about')); $collection->add(Route::get('/prices')); // will return MatchedRoute with first route var_dump($collection->match('/bar', 'GET')); // will return MatchedRoute with last route var_dump($collection->match('/prices', 'GET')); // will return false var_dump($collection->match('/prices', 'POST'))
还有可能使用多域名功能。
$pattern = new Pattern(); $pattern->register('urlAlias', '[a-zA-Z0-9-\.äÄöÖüÜß]+', true); $parser = new Parser($pattern); $main = new Domain('www.localhost.loc', $parser); $main->add(Route::get('/[foo]')); $main->add(Route::get('/')->setName('home')); $main->add(Route::get('/user')->setName('user')); $main->add(Route::get('/about')); $main->add(Route::get('/prices')); $api = new Domain('api.localhost.loc', $parser); $api->add(Route::get('/')->setName('home')); $api->add(Route::post('/user/[user_id]')->setName('user')); $domains = new MultiDomains(); $domains->add('main', $main); $domains->add('api', $api); // will match user route in api domain var_dump($domains->match('/user/asd', 'POST')); // will match last route in main domain var_dump($domains->match('/prices', 'GET')); // will generate user route for domain www.localhost.loc var_dump($domains->generate('user')); // will generate user route for domain api.localhost.loc var_dump($domains->generate('api:user', ['user_id' => 1]));
URL语法
规则
- 每个参数都必须有一个名称
- 一个URL定义中不应有重复的参数名称
- 名称应仅由字母和数字组成
- 定义了两种类型的模式,组合和严格
- 组合模式可以用AND和OR逻辑运算符组合
- 只有最后一个参数是可选的,即右侧有
?
字符
模式
模式可以根据具体情况和要求以不同的方式定义。有两种类型的模式。任何类型都可以由用户在Pattern
对象中定义和注册。所有模式都应放在[]
括号内。在这些括号内,您需要添加模式名称,这是必填项。如果模式中只有名称,则我们将匹配任何内容,直到下一个片段分隔符/
。
/test/[foo:n]{5}/bar
---------- pattern definition
--- name (required)
- separator between name and patterns (optional)
- pattern or pattern combination (optional)
--- quantifier (optional)
示例
/test/[foo]? foo can be anything and it is optional
/test/[foo:*] foo is everything until end of url
/test/[foo]/bar will match anything until next /
/test/[foo]{5,10}/bar will match anything that have 5 to 10 characters
/test/[foo]{5,}/bar will match anything that have min 5 characters
/test/[foo]{,10}/bar will match anything that have max 10 characters
/test/[foo:sha1]/bar will match only sha1 string (length 40 and hexadecimal)
/test/[foo:n]{5}/bar will match only number with 5 digits
/test/[foo:n|au]/bar will match numbers or string (capital letters), but no both
/test/[foo:n-a]/bar will match string containing number and letter
/test/[foo:<\d{5}>]/bar will match number with 5 digits (regex definition)
/test/[foo:(1|18|foo)]/bar will match numbers 1 or 18 or string foo
预定义的严格模式
md5 - md5 hash matching (32 characters and hexadecimal)
sha1 - sha1 hash matching (40 characters and hexadecimal)
* - will match everything until end of URL
预定义的组合模式
n - numeric (0-9)
a - alpha (a-zA-Z)
al - alpha lower (a-z)
au - alpha upper (A-Z)
c - characters (_-)
h - hexadecimal (a-fA-F0-9)
组合模式支持逻辑运算符OR |
和AND -
,并且可以组合这些模式。
n-a - numeric and alpha (0-9a-zA-Z)
c-au-n - characters and alpha upper and numeric (-_A-Z0-9)
n|a - numeric or alpha (0-9|a-zA-Z)
c|au|n - characters or alpha upper or numeric (-_|A-Z|0-9)
c-a|n - characters and alpha or numeric (-_a-zA-Z|0-9)
您还可以定义组合模式的量化。它在模式的自己的{}
大括号中定义。还有一个特殊的量化符?
,它将标记该模式为可选的,并且该问号只能出现在URL定义中的最后一个模式上。
{5} - exactly 5 characters
{1,5} - between 1 and 5 characters
{,5} - max 5 characters
{5,} - min 5 characters
? - pattern is optional
待办事项
- 创建更好的异常
基准测试
测试了https://github.com/tyler-sommer/php-router-benchmark
最坏情况的匹配结果,最后和未知路由与1000个路由相比。
最佳情况的匹配结果,第一个路由与1000个路由相比。
为什么这么快?
当我们尝试匹配某个路由,例如/bar/foo/test
时,系统会
- 尝试将此URL与固定URL进行匹配,其中URL是数组的键,如果找到匹配项,则返回结果,否则继续进行
- 尝试在正则表达式URL中匹配此URL。首先,我们将此URL分解为多种变体(如
/bar/foo/test
、/bar/foo
、/bar
、/
)。然后,我们将尝试检查每个变体,看是否能找到它的固定基础作为数组键。如果我们找到了,我们将在该路由集合内运行正则匹配(多个URL可以有相同的固定前缀)。