PHP路由系统


PHP routing system

我正在尝试创建一个基于注释的路由系统(类似于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);
        }
}
  1. 我认为这是一个好主意/解耦代码和入口点似乎在的任何地方都被使用

  2. 通常你不会去检查:第一个匹配的人就赢了。

这样做是个好主意,只要您在生产中缓存编译的路由。在路由时解析文件是有成本的,所以在不开发时要避免这种情况。

至于检查重复项,不要通过比较声明来进行检查。布线时只需检查即可。如果两个规则匹配,则抛出一个DuplicateRouteException。因此,在路由http://domain.com/test/a12/时,您将看到这两个路由都是有效的,并抛出异常。