我正在尝试创建一个基于注释的路由系统(类似于Recession Framework)。
<?php
class MyController extends ActionController {
/** !Route GET /hello/$firstname/$lastname **/
public function helloAction($firstname, $lastname) {
echo('Hello '.$firstname.' '.$lastname);
}
}
?>
如果我去http://domain.com/hello/James/Bond我得到
Hello James Bond
所以我有两个问题:
1) 这是个好主意吗?优点和缺点与集中式路由系统(如Zend Framework)。也许我看不出这种路由技术以后会出现什么问题。
2) 如果路由中有regexp,如何检查重复路由
<?php
class MyController extends ActionController {
/**
*!Route GET /test/$id = {
* id: [a-z0-9]
*}
**/
public function testAction($id) {
echo($id);
}
/**
*!Route GET /test/$id = {
* id: [0-9a-z]
*}
**/
public function otherTestAction($id) {
echo($id);
}
}
?>
我得到两条路线:/test/[a-z0-9]/
和/test/[0-9a-z]/
,如果我去http://domain.com/test/a12/
,这两条路线都是有效的。
感谢:)
尝试使用Java注释格式,它应该更容易统一解析。
它看起来像这样:
<?php
class MyController extends ActionController {
/**
@Route(get=/hello/$firstname/$lastname)
@OtherVal(var1=2,var2=foo)
@OtherVal2
**/
public function helloAction($firstname, $lastname) {
echo('Hello '.$firstname.' '.$lastname);
}
}
?>
并使用以下正则表达式解析注释:
@(?P<annotation>[A-Za-z0-9_]*)('((?P<params>[^')]*))?
当然,在可能的地方缓存这些内容,以避免重复解析。
缺点:
- 可能很难对服务器中所有方法的URL映射进行概述
- 若要更改URL,必须更改源代码,映射不会与应用程序分离
如果方法签名和映射总是像示例一样相关,则可以使用反射来提取映射,其中helloAction被提取为/hello,并且每个方法参数都是其子目录,按定义顺序排列。
那么注释就不需要复制URL,只需要复制该方法是一个端点的事实,类似于以下内容:
<?php
class MyController extends ActionController {
/** !endpoint(method=GET) **/
public function helloAction($firstname, $lastname) {
echo('Hello '.$firstname.' '.$lastname);
}
}
-
我认为这是一个好主意/解耦代码和入口点似乎在的任何地方都被使用
-
通常你不会去检查:第一个匹配的人就赢了。
这样做是个好主意,只要您在生产中缓存编译的路由。在路由时解析文件是有成本的,所以在不开发时要避免这种情况。
至于检查重复项,不要通过比较声明来进行检查。布线时只需检查即可。如果两个规则匹配,则抛出一个DuplicateRouteException
。因此,在路由http://domain.com/test/a12/
时,您将看到这两个路由都是有效的,并抛出异常。