Gus*_*avo 5 routing zend-framework
我已经阅读了有关路由和Zend文档的所有帖子,但我仍然无法解决这个问题.
我有一个包含两个模块的多语言应用程序:default和admin.语言选择工作正常(在Controller routeShutdown插件中),但我在配置路由器时遇到一些问题:
我想让这些URL工作:
/
/controller
/controller/action
/action (default controller)
/controller/param (default action)
/admin
/admin/admin-controller
/admin/admin-controller/action
Run Code Online (Sandbox Code Playgroud)
并使用语言选择器,它将是:
/en
/en/controller
/en/controller/action
/en/action (default controller)
/en/controller/param (default action)
/en/admin/admin-controller
/en/admin/admin-controller/action
Run Code Online (Sandbox Code Playgroud)
我把它添加到我的bootstap文件(index.php):
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->removeDefaultRoutes();
$router->addRoute('langmodcontrolleraction',
new Zend_Controller_Router_Route('/:lang/:module/:controller/:action',
array('lang' => ':lang'))
);
$router->addRoute('langmodcontroller',
new Zend_Controller_Router_Route('/:lang/:module/:controller',
array('lang' => ':lang',
'action' => 'index'))
);
$router->addRoute('langmod',
new Zend_Controller_Router_Route('/:lang/:module',
array('lang' => ':lang',
'action' => 'index',
'controller' => 'index'))
);
$router->addRoute('lang',
new Zend_Controller_Router_Route('/:lang',
array('lang' => ':lang',
'action' => 'index',
'controller' => 'index',
'module' => 'default'))
);
$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers',
'admin'=>BASE_PATH.'app/modules/admin/controllers'));
Run Code Online (Sandbox Code Playgroud)
为了检查路由器如何解析URL,我在routeShutdown插件中添加了一个var_dump:
进入/ en,我得到:
array
'lang' => string 'en' (length=2)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
'module' => string 'default' (length=7)
Run Code Online (Sandbox Code Playgroud)
这没关系.但是当我进入/ en/controller1时,我得到:
array
'lang' => string 'en' (length=2)
'module' => string 'controller1' (length=8)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
Run Code Online (Sandbox Code Playgroud)
将模块设置为"controller1".如何告诉路由器为模块设置默认值?对于像/ en/controller/param这样的URL?(将模块和操作设置为默认值)
我担心您需要稍微重新考虑一下您的URL方案,或者改变路由设置的方式,因为您已经遇到了ZF路由工作方式的两个限制.
首先,路由器不知道什么是有效的模块,控制器或动作; 它所做的只是将URL中的字符串与路径中的变量相匹配.它通过以相反的顺序连续检查每条路线,直到找到匹配为止.当你点击时/en/controller,它首先检查你的/:lang路线,这是不匹配的.然后检查/:lang/:module,哪个匹配,因为/:lang/:module匹配/任何/任何东西,除非你另有说明.
考虑到这一点,你将无法兼得:
/en/controller
/en/action
Run Code Online (Sandbox Code Playgroud)
除非您设置了一些限制,因为类似的URL /en/foo将始终与您最后定义的两个匹配.
如果你有相当少数的动作/控制器经常不会改变,最简单的方法是在两条路线中的第二条路线中硬编码一些可能的值,例如:
$router->addRoute('langmod', new Zend_Controller_Router_Route(
'/:lang/:module',
array(
'lang' => ':lang',
'action' => 'index',
'controller' => 'index'
),
array(
'module' => '(foo|bar|something)'
)
));
Run Code Online (Sandbox Code Playgroud)
用有效的模块名称替换foo,bar等.现在当你点击/en/controller1它时将不匹配此路由,因为controller1与为:module变量定义的正则表达式模式不匹配.然后,您需要一个单独的/:lang/:controller路径(或可能/:lang/:controller/:action)来匹配它.
您询问了如何为某些变量设置默认值.实际上你已经在你的一些路由中执行了这个操作,但是对于控制器/模块来说,你的希望方式不会很好.如果我们采用你的langmodcontroller路由并将其更改为:
$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
'/:lang/:module/:controller',
array(
'lang' => ':lang',
'controller' => 'index'
'action' => 'index'
)
));
Run Code Online (Sandbox Code Playgroud)
现在有一个控制器变量的默认值.如果我们假装这是唯一的路径,/en/blog那么现在请求匹配,并将请求参数设置为lang = en,module = blog,controller = index,action = index./en/blog/index/foo也会匹配这条路线,并会给你module = blog,controller = index,action = foo.但请注意,即使控制器=索引,您仍然需要在URL中.所以限制二是你总是需要URL中的变量(即使它被设置为你的默认值),只要你有一些不是默认值的东西.
考虑到这些限制,我建议你选择这样的东西(按此顺序定义):
/:lang/:controller/:action/ (with 'index' defaults for controller and action)
/:lang/:action (with 'action' restricted to some predefined values)
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default)
Run Code Online (Sandbox Code Playgroud)
这会给你这样的网址:
/en
/en/controller
/en/controller/action
/en/action
/en/controller/param
/en/admin/controller
/en/admin/controller/action
Run Code Online (Sandbox Code Playgroud)
这几乎就是你追求的目标.
ZF中的路由非常强大,您只需知道它的怪癖.