1

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

PHP 也有一个自动包含功能,它需要一个一致的命名系统来为你的类使用。例如,如果我想获得类 Foo 的一个实例,我需要将文件命名为 Foo.php,并且里面将是一个名为 Foo 的类。

不幸的是,这些机制同时对命名系统提出了相互竞争的要求。该网址非常“正面”,因此,客户通常需要它来反映特定页面的内容。例如,如果我有一个指向某个地点的页面,客户可能需要此页面位于http://example.com/venues/directions/. 稍后内容可能会发生变化,并且会场数量减少到 1,现在客户希望读取 url http://example.com/venue/directions/。显然,这是一个非常微不足道的例子,但我认为偶尔更改 url 的需要是很清楚的。

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

这个问题有哪些解决方案?在我看来,需要一个目录来存储 url 和控制器之间的关系,以便任何 url 都可以用来调用任何控制器,而不管它们的名称是什么。因此,我们将有一个场地控制器和一个场地 url,当客户端请求更改 url 时,我们只需在目录中进行更改,将新的“场地”转换为“场地”。

我认为最好的方法是在数据库表中,但这需要对每个用户请求进行额外的查询。数据库是实现目录的正确方法吗?目录甚至是解决上述问题的最佳方法吗?这个问题首先是一个问题吗???

4

2 回答 2

4

我看到的一些解决方案是明确指定到控制器/动作的路由“连接”。

例如,在NiceDog中,您可以指定如下路线

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

允许正则表达式匹配 URL。(上面的表达式将匹配venue/directionsor 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.');
}
于 2010-06-21T13:55:21.450 回答
0

解决此问题的一个好方法是让 MVC 框架允许您指定自己的路由规则。例如,请参阅CodeIgniter 框架文档中的URI 路由

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

于 2010-06-21T13:35:09.860 回答