简体   繁体   English

Zend Framework 2的默认模块

[英]Zend Framework 2 default module

In ZF1 you did not have to include the module in the URL; 在ZF1中,您不必在URL中包含该模块; if it was not provided, it would default to... the default module. 如果未提供,则默认为...默认模块。 How can this be accomplished in ZF2? 如何在ZF2中实现这一目标? I have used the skeleton application to get up and running, but it seems as if I always need to include the module name, eg /application/controller/action . 我已经使用了框架应用程序来启动和运行,但似乎我总是需要包含模块名称,例如/application/controller/action

I figured I could work around this by creating a route with two "placeholders"; 我想我可以通过创建一个包含两个“占位符”的路线来解决这个问题; controller and action, and then set the default module to "application". 控制器和操作,然后将默认模块设置为“应用程序”。 I would then put this in /config/autoload/global.php (or perhaps /config/application.config.php ) so that the route applies for all of my application. 然后我将它放在/config/autoload/global.php (或者可能是/config/application.config.php )中,以便该路由适用于我的所有应用程序。 However, I am getting the error message that the URL could not be matched by routing, even if I hard code the route to something like /user/index . 但是,我收到错误消息,即路由无法匹配URL,即使我将路由硬编码为/user/index

I tried the code below. 我试过下面的代码。

return array(
    'router' => array(
        'routes' => array(
            'nomodule' => array(
                'type' => 'Zend\Mvc\Router\Http\Literal',
                '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(
                        'module' => 'Application' // Not sure of the syntax here
                    )
                )
            ),
        )
    )
);

As I wrote as a comment, I am not sure if my problem is with the defaults syntax, but I wouldn't think so as the same happens if I hard code the route and remove all defaults. 正如我作为评论写的那样,我不确定我的问题是否是默认语法,但我不这么认为,如果我硬编码路由并删除所有默认值,也会发生同样的情况。 I also tried to experiment with it based on examples in the skeleton application, but without luck. 我还试图根据骨架应用程序中的示例进行实验,但没有运气。 Am I going about it the wrong way? 我是以错误的方式去做的吗? Is there a better approach? 有更好的方法吗? Or did I just make a mistake? 或者我只是犯了一个错误?

Thanks in advance. 提前致谢。

Edit: For the code to make it work, see the answer. 编辑:要使代码生效,请参阅答案。 For an explanation of how it works, read this article . 对于它是如何工作的解释,请阅读这篇文章

Note: Explicit routes are strongly recommended over wildcard. 注意:强烈建议使用显式路由而不是通配符。

You used Zend\\Mvc\\Router\\Http\\Literal route type in your attempt, as you might guess it is literal, ie exact match. 您在尝试中使用了Zend \\ Mvc \\ Router \\ Http \\ Literal路由类型,因为您可能猜到它是文字的,即完全匹配。 To make it work you need segment route type. 要使其工作,您需要分段路由类型。

Check application route in Zend Skeleton Application config and it's child route default . 检查Zend Skeleton Application config中的application路由,它的子路由是default It does exactly what you are trying to do. 它完全符合您的要求。

As for modules - there is no such thing as 'module' from your code perspective. 至于模块 - 从代码的角度来看,没有'模块'这样的东西。 Module registers resources on startup and it is no longer relevant after that point. 模块在启动时注册资源,在此之后不再相关。 In zf2 you specify exact controller by class or alias name under which controller registered with controllerManager 在zf2中,您可以通过类或别名指定精确的控制器,在该控制器上向controllerManager注册

// module\Application\config\module.config.php
return array(
    'router' => array(
        'routes' => array(
            'home' => array(
                'type' => 'Zend\Mvc\Router\Http\Literal',
                'options' => array(
                    'route'    => '/',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action'     => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    '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(
                                'action' => 'index',
                                '__NAMESPACE__' => 'Application\Controller'
                            )
                        )
                    )
                )
            )
        )
    ),
    'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController',
            'Application\Controller\User' => 'Application\Controller\UserController'
        ),
    )
);

As I stated in comment under @Xerkus answer, it doesn't work for all URLs: 正如我在@Xerkus回答中的评论中所述,它不适用于所有网址:

/application/index/index
/application/index
/application
/index/index
/index
/

I have added also testAction() to IndexController and TestController with same actions as IndexController , so I could test my solution on following routes as well: 我还使用与IndexController相同的操作将testAction()添加到IndexControllerTestController ,因此我也可以在以下路由上测试我的解决方案:

/index/test
/test/index
/test/test
/test

So after some research ( here and here mainly) I prepared solution working for all of them. 经过一些研究( 这里这里主要是),我准备了解决所有这些问题的解决方案。 I will paste my whole module.config.php array: 我将粘贴我的整个module.config.php数组:

return array(
    'router' => array(
        'routes' => array(
            'home' => array(
                'type' => 'Literal',
                'options' => array(
                    'route'    => '/',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action'     => 'index',
                    ),
                ),
            ),
            'noModule' => 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(
                        '__NAMESPACE__' => 'Application\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
            ),
            // The following is a route to simplify getting started creating
            // new controllers and actions without needing to create a new
            // module. Simply drop new controllers in, and you can access them
            // using the path /application/:controller/:action
            'application' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/application',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Application\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    '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(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
        ),
    ),
    'translator' => array(
        'locale' => 'en_US',
        'translation_file_patterns' => array(
            array(
                'type'     => 'gettext',
                'base_dir' => __DIR__ . '/../language',
                'pattern'  => '%s.mo',
            ),
        ),
    ),
    'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController',
            'Application\Controller\Test' => 'Application\Controller\TestController'
        ),
    ),
    'view_manager' => array(
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => array(
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ),
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),
);

In comparison with Zend 2 Skeleteon Application config I've added noModule route, and new controller invokable - test . 与Zend 2 Skeleteon Application配置相比,我添加了noModule路由,并且新controller invokable - test Of course noModule route includes Application/Controller namespace, so basing on this fact, you can set whatever default module you need. 当然noModule路由包括Application/Controller命名空间,因此基于这个事实,您可以设置所需的任何默认模块。 Now it works as it should. 现在它可以正常工作。

Of course remember that your noModule route should be defined in first module from application.config.php to ensure that it will always take precedence. 当然记住,应该在application.config.php第一个模块中定义noModule路由,以确保它始终优先。 Also remember that default module solution should be done carefully, to avoid conflicts between controllers and modules names, eg if you name your next module Index , then clearly you will have a naming conflict with IndexController in Application module. 还要记住,应该小心地完成默认模块解决方案,以避免控制器和模块名称之间的冲突,例如,如果您命名下一个模块Index ,那么显然您将在Application模块中与IndexController发生命名冲突。

I'm new to ZF in general and I just started learning it, so tried this and it worked for me. 我是ZF的新手,我刚刚开始学习它,所以尝试了这个,它对我有用。 Just to be sure, u want to change your default module when you go to your domain URL and don't type in a controller name, right? 只是为了确定,你想要在转到你的域名网址时更改你的默认模块,而不是输入控制器名称,对吧?

Go to your module.config.php 转到你的module.config.php

 'router' => array(
    'routes' => array(
        'album WITH CONTROLLER IN URL' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/album[/:action]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                ),
                'defaults' => array(
                    'controller' => 'Album\Controller\Album',
                    'action'     => 'index',
                ),
            ),
        ),
        'album WITHOUT CONTROLLER IN URL' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/[:action]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                ),
                'defaults' => array(
                    'controller' => 'Album\Controller\Album',
                    'action'     => 'index',
                ),
            ),
        ),
        'SET IT AS YOUR HOMEPAGE' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/',
                'defaults' => array(
                    'controller' => 'Album\Controller\Album',
                    'action'     => 'index',
                ),
            ),
        ),
    ),
),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM