在ZF1中,您不必在URL中包含该模块;如果未提供,则默认为...默认模块。如何在ZF2中实现这一目标?我已经使用了骨架应用程序来启动和运行,但好像我总是需要包含模块名称,例如/application/controller/action
。
我想我可以通过创建一个包含两个“占位符”的路线来解决这个问题;控制器和操作,然后将默认模块设置为“应用程序”。然后我会将其放在/config/autoload/global.php
(或者/config/application.config.php
)中,以便该路由适用于我的所有应用程序。但是,我收到错误消息,即路由无法匹配URL,即使我将路由硬编码为类似/user/index
的内容。
我尝试了下面的代码。
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
)
)
),
)
)
);
正如我作为评论写的那样,我不确定我的问题是否是默认语法,但我不这么认为,如果我硬编码路由并删除所有默认值,也会发生同样的情况。我还试图根据骨架应用程序中的示例进行实验,但没有运气。我是以错误的方式去做的吗?有更好的方法吗?或者我只是犯了错误?
提前致谢。
修改:要使代码生效,请参阅答案。有关 的工作原理的解释,请阅读this article。
答案 0 :(得分:11)
注意:强烈建议使用明确路由而不是通配符。
您在尝试中使用了Zend \ Mvc \ Router \ Http \ Literal路由类型,因为您可能会猜测它是文字的,即完全匹配。要使其工作,您需要分段路由类型。
Check application
route in Zend Skeleton Application config和它的子路线default
。
它完全符合您的要求。
至于模块 - 从代码的角度来看,没有“模块”这样的东西。模块在启动时注册资源,在此之后不再相关。 在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'
),
)
);
答案 1 :(得分:1)
正如我在@Xerkus回答中的评论中所述,它不适用于所有网址:
/application/index/index
/application/index
/application
/index/index
/index
/
我已将testAction()
添加到IndexController
和TestController
,其操作与IndexController
相同,因此我也可以在以下路线上测试我的解决方案:
/index/test
/test/index
/test/test
/test
因此,经过一些研究(主要是here和here),我为所有人准备了解决方案。我将粘贴整个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',
),
),
);
与Zend 2 Skeleteon Application配置相比,我添加了noModule
路由和新controller invokable
- test
。当然noModule
路由包含Application/Controller
命名空间,因此基于这个事实,您可以设置所需的任何默认模块。现在它可以正常工作。
当然要记住,noModule
路由应该在application.config.php
的第一个模块中定义,以确保它始终优先。还要记住,应该小心地完成默认模块解决方案,以避免控制器和模块名称之间的冲突,例如:如果您为下一个模块Index
命名,那么很明显,IndexController
模块中的Application
会出现命名冲突。
答案 2 :(得分:0)
我是ZF的新手,我刚开始学习它,所以尝试了这个,它对我有用。只是为了确定,你想在转到域名网址时更改默认模块,而不是输入控制器名称,对吗?
转到你的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',
),
),
),
),
),