ZF2:子路由永远不匹配——为什么?
ZF2: Child route is never matched – why?
我的模块在 Zend Framework 2 中的 module.config.php
看起来像这样:
return array(
'controllers' => array(
'invokables' => array(
'Test\Controller\A' => 'Test\Controller\AController',
'Test\Controller\B' => 'Test\Controller\BController',
'Test\Controller\C' => 'Test\Controller\CController',
),
),
'router' => array(
'routes' => array(
'some-test' => array(
'type' => 'literal',
'options' => array(
'route' => '/a',
'defaults' => array(
'controller' => 'Test\Controller\A',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'some-other-test' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:controller[/:action]]',
'defaults' => array(
'action' => 'index',
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
文字路由有效,/a
正确匹配,而 /a/
导致 404,这很好且合乎逻辑。
对于分段路线,情况看起来有点不同。不管我输入什么,路由 从未 匹配。所以路线 /a/b
失败了,我不明白。
根据上面的子路由设置,尾部斜杠是可选的,但是当它存在时,还需要指定控制器名称。如果是这种情况,则应调用指定控制器的索引操作——在本例中来自 BController。
如果在控制器名称后添加尾部斜杠,则需要指定操作。
即使我输入 /a/b/index
,我也会收到 404 错误:
The requested controller could not be mapped to an existing controller class.
Controller:
b(resolves to invalid controller class or alias: b)
由此我得出结论,整个子路由都不起作用,不仅是 default/fallback 选项。为什么子路由一直不匹配?
您收到的错误表明 Zend 路由器无法将控制器 b
映射到现有的 class。它需要知道您的控制器 class 在应用程序中的位置。
一个可能的解决方案是在 module.config
文件的 invokables
中将控制器的名称作为 aliases。例如:'a' => 'Test\Controller\AController'
为AController
。路由 /a
匹配并且不会抛出错误,因为您在路由配置中设置了默认控制器。
因此您只需要更改这部分代码。这样,控制器将通过 invokables
数组中的 key value
被调用:
'controllers' => array(
'invokables' => array(
'a' => 'Test\Controller\AController',
'b' => 'Test\Controller\BController',
'c' => 'Test\Controller\CController',
),
),
另一种解决方案是在路由配置中添加控制器的 __NAMESPACE__
,这样您就可以保留与现在相同的别名。
只需像这样修改您的代码:
'router' => array(
'routes' => array(
'some-test' => array(
'type' => 'literal',
'options' => array(
'route' => '/a',
'defaults' => array(
'__NAMESPACE__' => 'Test\Controller',//<---add it here
'controller' => 'Test\Controller\A',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:controller[/:action]]',
'defaults' => array(
'action' => 'index',
),
),
),
),
),
),
),
我的模块在 Zend Framework 2 中的 module.config.php
看起来像这样:
return array(
'controllers' => array(
'invokables' => array(
'Test\Controller\A' => 'Test\Controller\AController',
'Test\Controller\B' => 'Test\Controller\BController',
'Test\Controller\C' => 'Test\Controller\CController',
),
),
'router' => array(
'routes' => array(
'some-test' => array(
'type' => 'literal',
'options' => array(
'route' => '/a',
'defaults' => array(
'controller' => 'Test\Controller\A',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'some-other-test' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:controller[/:action]]',
'defaults' => array(
'action' => 'index',
),
),
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
文字路由有效,/a
正确匹配,而 /a/
导致 404,这很好且合乎逻辑。
对于分段路线,情况看起来有点不同。不管我输入什么,路由 从未 匹配。所以路线 /a/b
失败了,我不明白。
根据上面的子路由设置,尾部斜杠是可选的,但是当它存在时,还需要指定控制器名称。如果是这种情况,则应调用指定控制器的索引操作——在本例中来自 BController。
如果在控制器名称后添加尾部斜杠,则需要指定操作。
即使我输入 /a/b/index
,我也会收到 404 错误:
The requested controller could not be mapped to an existing controller class.
Controller:
b(resolves to invalid controller class or alias: b)
由此我得出结论,整个子路由都不起作用,不仅是 default/fallback 选项。为什么子路由一直不匹配?
您收到的错误表明 Zend 路由器无法将控制器 b
映射到现有的 class。它需要知道您的控制器 class 在应用程序中的位置。
一个可能的解决方案是在 module.config
文件的 invokables
中将控制器的名称作为 aliases。例如:'a' => 'Test\Controller\AController'
为AController
。路由 /a
匹配并且不会抛出错误,因为您在路由配置中设置了默认控制器。
因此您只需要更改这部分代码。这样,控制器将通过 invokables
数组中的 key value
被调用:
'controllers' => array(
'invokables' => array(
'a' => 'Test\Controller\AController',
'b' => 'Test\Controller\BController',
'c' => 'Test\Controller\CController',
),
),
另一种解决方案是在路由配置中添加控制器的 __NAMESPACE__
,这样您就可以保留与现在相同的别名。
只需像这样修改您的代码:
'router' => array(
'routes' => array(
'some-test' => array(
'type' => 'literal',
'options' => array(
'route' => '/a',
'defaults' => array(
'__NAMESPACE__' => 'Test\Controller',//<---add it here
'controller' => 'Test\Controller\A',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:controller[/:action]]',
'defaults' => array(
'action' => 'index',
),
),
),
),
),
),
),