您尝试构建的路线并没有什么特别的异国情调。如果没有准确如何描述您的路由/调度是如何中断的,很难识别您可能遇到的任何深奥的路由行为(相信我,有一些)。
在详细说明之前,我强烈建议您始终使用反向路由来构建您的 URL(即 $html->url(array('controller'=>'homes','action'=>'index')); 而不是 $html->url('/homes/index')。这是一个很小的性能损失,最终会让您免于麻烦。
让我们浏览您的示例路由,我将尝试解释如何在您的视图中构建匹配的 URL,并突出显示您遇到的潜在问题。
Router::connect('/:filter/h/:id', array('controller'=>'homes','action'=>'view'));
您将使用以下反向路由在您的视图中构建一个 URL:
$html->url( array(
'controller'=>'homes','action'=>'view',
'id'=>$some_id,'filter'=>$some_filter
));
请注意,我传递了'id' 和'filter' 键,而不是只传递相应的变量。这是因为 Cake 按顺序处理没有键的反向路由参数。所以如果你打电话:
$some_filter = 'foobar';
$some_id = 1234;
$html->url( array('controller'=>'homes','action'=>'view',$some_id,$some_filter));
你最终会得到这个网址:
/1234/h/foobar
哪个是倒退的。
您可能遇到的另一个问题是此路由如何分派到控制器操作。默认情况下,Cake 将按照它们在路由定义中出现的顺序传递路由请求的所有参数,除非另有说明。因此,对于上面的路线,Cake 会调用:
HomesController::view( $filter, $id );
如果您希望HomesController::view 的第一个参数为$id,则需要在路由定义中指定:
// This route definition...
Router::connect(
'/:filter/h/:id',
array( 'controller'=>'homes', 'action'=>'view' ),
array(
'pass' => array( 'id', 'filter' )
)
);
// ...invokes the controller action:
// HomesController::view( $id, $filter );
Router::connect 的第三个数组参数的 'pass' 元素告诉 Cake 哪些路由参数以及以什么顺序传递给控制器动作。你可以从数组中删除'filter',Cake 会调用这个动作:
HomesController::view( $id );
在这种情况下,Cake 仍然捕获 $filter 并将其作为 Controller::params 属性的元素提供给控制器。您可以通过寻址$this->params['filter'] 来访问它的值。
您提供的第二条路线是:
Router::connect('/admin/:controller/:action/:id');
对于管理员路由,您实际上不需要定义以'admin' 开头的特定路由。您只需开启admin routing。在您的/app/config/core.php 中,查找并取消注释该行:
Configure::write('Routing.admin', 'admin');
这允许您定义一组带有admin_ 前缀的操作(例如admin_edit、admin_publish 等),这些操作由/admin/homes/edit/1234 之类的URL 分派到。在您看来,您可以像这样构建反向路由:
$html->url( array(
'controller'=>'homes','action'=>'edit',1234
'admin'=>true
));
注意'admin'=>true 部分,它通知 Cake 你正在请求一个以管理员为前缀的路由。