我有一条路线:
((?<directory>\w+)/?)?((?<controller>\w+)/?)?((?<action>\w+)/?)?((?<id>\d+))?
它工作正常,但它导致我的系统必须包含到子路由的所有路由的默认控制器(索引)。例如,如果我的页面URI是/blog/post
(其中blog是目录,帖子就是操作),我的实际URI必须是blog/index/post
- 我希望能够回到仅使用blog/post
。
所以,我希望将它发送到:
directory = blog
controller = index
action = post
显然,当第二个参数实际上是控制器时,这会导致问题。例如,directory/controller/action
将被错误地路由。
是否有一种路由方法可以检测到有三个单词参数,可能后跟一个数字参数,可以做我需要的工作?
对于诽谤:
param/param/param(?/id)
将是:directory/controller/action(/id)
param/param(?/id)
将是:directory/default_controller/action(/id)
答案 0 :(得分:3)
我实际上认为你想用blog/index/post
别名blog/post
;将它作为一条路线插入到你所拥有的“全能”路线之前; “一大鞋适合所有人”的方法并不总是最好的。特别是,如果你只有1个这样的特殊用例。
修改强>
使用正则表达式模式搞清楚。这是一个可能有用的片段(我把它放在一个PHP测试用例中,但你可以很容易地将它解耦)
public function testRoutePatterns(){
$data = array(
array(
//most specific: word/word/word/id
'~^(?P<directory>\w+)/(?P<controller>\w+)/(?P<action>\w+)/(?P<id>.*)$~i',
'myModule/blog/post/some-id',
array('directory'=>'myModule', 'controller'=>'blog', 'action'=>'post', 'id'=>'some-id'),
true
),
array(
//less specific: word/word/id
'~^(?P<directory>\w+)/(?P<action>\w+)/(?P<id>.*)$~i',
'blog/post/some-id',
array('directory'=>'blog', 'action'=>'post'), //need to inject "index" controller via "defaults()" here i guess
true
),
);
foreach ($data as $d) {
$matches = array();
list($pattern, $subject, $expected, $bool) = $d;
$actual = (bool) preg_match($pattern, $subject, $matches);
$this->assertEquals($bool, $actual); //assert matching
$this->assertEquals(array(), array_diff($expected, $matches)); //$expected contained in $matches
}
}
答案 1 :(得分:0)
如this answer所述,如果你有这样的路线:
Route::set('route_name', 'directory/controller/action')
->defaults(array(
'directory' => 'biz',
'controller' => 'foo',
'action' => 'bar',
));
你应该有这样的目录结构:
/application/classes/controller/biz/foo.php