2

我今天刚刚发现 zf2 并不喜欢两个控制器具有相同的名称,即使它们不在同一个模块中。但是,我需要能够调用 localhost/users/types 和 localhost/messages/types

目前,我的两个控制器具有相同的名称。我还发现无论模块的名称是什么,我总是得到消息/类型的结果,即使使用 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' => 'Messages'(我们永远不知道:p)但我遇到了 404 错误。Tasks 模块的 module.config.php 是相同的,但用于任务。我最初有别名,但是在我在某个地方读到这不是很推荐之后我删除了它们。

还有一件事,这是一个 REST API,我所有的控制器都扩展了 AbstractRestfulController(如果这很重要)

任何人都知道如何使我的 2 url 工作?

谢谢 :)

4

2 回答 2

2

可调用或服务的别名以及其他任何东西都应该是唯一的。如果它们不是唯一的,则它们可能会按照模块本身的加载顺序被另一个模块覆盖。这意味着:在设置可调用对象或任何类型的别名时,请确保别名是唯一有意义的。我个人这样命名我的控制器:

'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-indexindexAction()
  • 如果路由是/messages/types它保持在控制器别名messages-controller-index但去typesAction()
  • 如果路由是如果路由到/tasks控制器别名tasks-controller-indexindexAction()
  • 如果路由是/tasks/types它保持在控制器别名tasks-controller-index但去typesAction()

您显然可以更改其背后的控制器别名和含义。如果你想为一个路由添加一个 ID,就像/messages/types/1你要为类型路由构建一个子路由segment并检查一个 [:id] 参数,其约束应该是数字:) 检查官方 ZF2手册了解更多信息,我现在很懒:P

于 2012-11-27T14:25:08.920 回答
1

tl;dr:确保您__NAMESPACE__的路由定义中有一个默认值,然后确保您的所有服务名称都以它为前缀。通常,该值将匹配您的模块命名空间。

对于更长的解释:

我会直言不讳:在您的路由中拥有一个映射到控制器的动态段(:controller在您的示例中)是一种非常糟糕的做法。原因是如果有人发现了这一点,他们可以进行控制器注入,并请求一个不应通过该特定路由路由的控制器。

此外,这种做法很容易导致冲突,特别是如果您__NAMESPACE__在路由配置中省略了默认值 - 根据问题,您已经发现了默认值。

于 2013-03-22T20:27:36.947 回答