代码之家  ›  专栏  ›  技术社区  ›  Rupert Madden-Abbott

允许路由器从数据库中查找控制器是个好主意吗?

  •  1
  • Rupert Madden-Abbott  · 技术社区  · 15 年前

    在大多数PHP MVC设计结构教程中,router类用于获取用户输入并查找正确的控制器,以便准确地处理输入。输入通常采用url的形式。例如 http://example.com/foo/bar/ 将要求路由器找到名为foo的控制器并启动方法栏。

    PHP还有一个auto include函数,它要求为类使用一致的命名系统。例如,如果我想得到一个Foo类的实例,我需要一个名为Foo.php的文件,里面是一个名为Foo的类。

    不幸的是,这些机制同时对命名系统提出了相互竞争的要求。url是非常“正面”的,因此,客户端通常需要它来反映特定页面的内容。例如,如果我有一个页面,提供一个地点的方向,客户可能需要这个页面 http://example.com/venues/directions/ http://example.com/venue/directions/ . 很明显,这是一个非常微不足道的例子,但我认为偶尔更改url的必要性是显而易见的。

    由于url与控制器类的连接非常紧密,因此对url的更改意味着类文件名、类名本身以及该类的任何实例都需要更改。对我来说,对于更复杂的系统来说,这似乎非常耗时。

    这个问题有什么解决办法?在我看来,目录的排序将是必要的,其中关系的网址和控制器之间的存储,以便任何网址可以用来调用任何控制器,无论是什么名字。因此,我们将有一个场馆控制器和一个场馆url,当客户端请求更改url时,我们只需更改目录,将新的“场馆”转换为“场馆”。

    2 回复  |  直到 15 年前
        1
  •  4
  •   Austin Hyde    15 年前

    我见过的一些解决方案是显式地指定到控制器/操作的路由“连接”。

    NiceDog ,可以指定如下路径

    R('venues?/directions')
      ->controller('VenueController')
      ->action('directionsAction')
      ->on('GET');
    

    venue/directions venues/directions )我喜欢这种方法,因为它将控制器命名方案与URL命名方案分离。

    另一种更基于配置的方法是使用某种显式映射:

    $routes = array(
        'venues?' =>
          array('controller'=>'VenueController','action'=>'indexAction'),
        'venues?/directions' =>
          array('controller'=>'VenueController','action'=>'directionsAction')
    );
    

    然后是一个简单的分派函数:

    function dispatch($url,$routes) {
        foreach ($routes as $pattern=>$map) {
            if (preg_match($pattern,$url,$matches)) {
                $controller = new $map['controller']();
                $action = $map['action'];
                call_user_func_array(
                  array($controller,$action),
                  array_slice($matches,1)
                );
                return true;
            }
        }
        throw new Exception('Route not found.');
    }
    
        2
  •  0
  •   Justin Ethier    15 年前

    解决这个问题的一个好方法是MVC框架允许您指定自己的路由规则。例如,请参见 URI Routing

    为了配合您的示例,这将允许您重新映射 /venues/ /venue .

    推荐文章