Zend Framework 2路由子域名到模块

8
在长时间的无功搜索后,在我放弃之前,我想问一下:
有没有办法将子域路由到Zend Framework 2中的一个模块?像这样:
子域 => 模块 api.site.com => api dev.site.com => dev admin.site.com => admin site.com => public ...
我尝试像这样做,但我不能访问除默认(Index)以外的控制器。
'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Application\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            )
        )
    ),
),

感谢您抽出时间来帮助我。
2个回答

5

Zend Framework 2没有将路由映射到模块的概念; 所有路由映射都是在URI模式(用于HTTP路由)和特定控制器类之间进行的。 也就是说,Zend\Mvc提供了一个事件侦听器(Zend\Mvc\ModuleRouteListener),它允许您定义一个URI模式,该模式基于给定的模式映射到多个控制器,从而模拟“模块路由”。 要定义这样的路由,请将其放置在您的路由配置中:

'router' => array(
    'routes' => array(
         // This defines the hostname route which forms the base
         // of each "child" route
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Application\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                // This Segment route captures the requested controller
                // and action from the URI and, through ModuleRouteListener,
                // selects the correct controller class to use
                'default' => array(
                    'type'    => 'Segment',
                    'options' => array(
                        'route'    => '/[:controller[/:action]]',
                        'constraints' => array(
                            'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                        ),
                        'defaults' => array(
                            'controller' => 'Index',
                            'action'     => 'index',
                        ),
                    ),
                ),
            ),
        ),
    ),
),

(点击这里查看ZendSkeletonApplication的示例)

然而,这只是方程式的一半。您还必须使用特定的命名格式在模块中注册每个控制器类。这也可以通过相同的配置文件完成:

'controllers' => array(
    'invokables' => array(
        'Application\Controller\Index' => 'Application\Controller\IndexController'
    ),
),

数组键是别名 ModuleRouteListener 将使用它来查找正确的控制器,它必须采用以下格式:
<Namespace>\<Controller>\<Action>

这个数组键所赋的值是控制器类的完全限定名。
点击此处查看ZendSkeletonApplication中的示例
注意:如果您没有使用ZendSkeletonApplication或删除了它的默认应用程序模块,则需要在自己的模块中注册ModuleRouteListener。 点击此处查看ZendSkeletonApplication如何注册此侦听器的示例

2
非常感谢您清晰而精确的解释。我采用了您的解决方案。我在这个问题上挣扎了很久。 - severin.julien
我使用 MAMP Pro 并在我的虚拟主机名称上创建了一个子域,所以当我使用 reseller.myhost.com/test 时它是可以的,但如果我写 reseller.myhost.com 它会跳转到应用程序的索引而不是我的模块的 indexaction。 - babak faghihian
@Sapher 但是为什么其他模块的其他路由在当前子域上可以工作呢? - babak faghihian

4
如果我正确地理解了DASPRIDS Rounter Presentation的第39张幻灯片,那么定义子域主机只需要按模块进行简单设置,例如:
'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'Hostname',
            'options' => array(
                'route' => 'api.site.com',
                'defaults' => array(
                    '__NAMESPACE__' => 'Api\Controller',
                    'controller'    => 'Index',
                    'action'        => 'index',
                ),
            )
        )
    ),
),

对于每个模块,您需要单独执行此操作。

抱歉,如果这听起来很愚蠢,但是您是否需要为API子域注册新的Web服务器虚拟主机? - Marcel Djaman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接