我今天刚刚发现zf2并不真正喜欢2个控制器具有相同名称,即使它们不在同一个模块中。 但是,我需要能够打电话 本地主机/用户/类型 和 本地主机/消息/类型
目前,我的两个控制器名称相同。 我还发现无论模块的名称是什么,我总是得到消息/类型的结果,即使是localhost / nonexistingmodule / types oO
这是我的module.config.php的样子:
return array(
'controllers' => array(
'invokales' => array(
'messages' => 'Messages\Controller\MessagesController,
'messages' => 'Messages\Controller\TypesController,
),
),
'di' => array(
'instance' => array(
'alias' = array(),
),
),
'router' => array(
'routes => array(
'restful' => array(
'type' => 'Zend\Mvc\Router\Http\Segment'
'options' => array(
'route' => '/Messages/:controller[.:formatter][/:id],
'constraints' => array(
'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'formater' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[a-zA-Z0-9_-]*',
),
'defaults' => array(
'module' => 'Messages',
),
),
),
),
),
'view_manager' => array( ... ),
);
我试过设置'module'=>约束中的'消息'(我们永远不知道:p)但我有404错误。 任务模块的module.config.php与任务相同。 我原来有别名,但是在我读到某个地方之后我将它们删除了。这不是很复杂的。
还有一件事,这是一个REST API,我的所有控制器都扩展了AbstractRestfulController(如果这很重要)
任何人都知道如何让我的2个网址工作?
谢谢:)
答案 0 :(得分:2)
invokables或服务的别名以及其他任何内容都应该是唯一的。如果它们不是唯一的,则它们可能被其他模块按其自身加载的模块顺序覆盖。这意味着:在设置invokable或任何类型的别名时,请确保别名唯一和有意义。就个人而言,我将控制器命名为:
'invokables' => array(
'mymodule-controller-controllername' => 'Mymodule\Controller\ControllernameController'
)
与服务或任何其他种类的别名相同
'services' => array(
'mymodule-service-servicename' => 'Mymodule\Service\Classname'
)
文档遵循命名空间样式的语法,如...
'invokables' => array(
'Mymodule\Controller\Controllername' => 'Mymodule\Controller\ControllernameController'
)
...我个人觉得完全令人困惑,因为它类似于命名空间方式而且并不真正意味着它只是一个别名/密钥
现在你的评论问题我不明白。您想要将一条路线与两个不同的控制器相匹配?那是不可能的,毫无意义的。
使用路由配置回复更新
对于路由配置,您有几种可能的方法。我个人非常努力建立文字路线,因为它们是最快的,但也需要大量的人工关注。或者,有段路线可以抑制它们的魔力。我将为您介绍字面方法:
模块消息
'controllers' => array(
'invokables' => array(
'messages-controller-index' => 'Messages\Controller\IndexController',
)
),
'router' => array(
'routes' => array(
'messages' => array(
'type' => 'literal',
'options' => array(
'route' => '/messages',
'defaults' => array(
'controller' => 'messages-controller-index',
'action' => 'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'types' => array(
'type' => 'literal',
'options' => array(
'route' => '/types',
'defaults' => array(
'action' => 'types'
)
)
)
)
)
)
)
模块任务
'controllers' => array(
'invokables' => array(
'tasks-controller-index' => 'Tasks\Controller\IndexController',
)
),
'router' => array(
'routes' => array(
'tasks' => array(
'type' => 'literal',
'options' => array(
'route' => '/tasks',
'defaults' => array(
'controller' => 'tasks-controller-index',
'action' => 'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'types' => array(
'type' => 'literal',
'options' => array(
'route' => '/types',
'defaults' => array(
'action' => 'types'
)
)
)
)
)
)
)
那么正在发生的事情是:
/messages
,则路由到控制器别名messages-controller-index
indexAction()
/messages/types
,则会保留在控制器别名messages-controller-index
,但会转到typesAction()
/tasks
,则路由到控制器别名tasks-controller-index
indexAction()
/tasks/types
,则会保留在控制器别名tasks-controller-index
,但会转到typesAction()
你显然可以改变控制器别名和含义。如果您想为/messages/types/1
之类的路由添加ID,您需要构建一个到segment
类型的类型路由的子路由,并检查[:id]参数,其参数为约束应该是数字:)查看官方ZF2手册了解更多信息,我现在很懒:P
答案 1 :(得分:1)
tl; dr:确保路由定义中有__NAMESPACE__
默认值,然后确保所有服务名称都带有前缀。通常,该值将与您的模块名称空间匹配。
更长的解释:
我会直言不讳:在你的路线中有一个映射到控制器的动态段(在你的例子中是:controller
)是一个非常糟糕的做法。原因是,如果有人发现这一点,他们可以进行控制器注入,并请求一个不应该被这条特定路由路由的控制器。
此外,这种做法很容易导致冲突,特别是如果您在路线配置中省略__NAMESPACE__
默认值 - 根据问题,您已经发现了这一点。