gpt4 book ai didi

zend-framework - Zend 路由问题

转载 作者:行者123 更新时间:2023-12-04 18:48:49 25 4
gpt4 key购买 nike

我已经阅读了所有关于路由和 Zend 文档的帖子,但我仍然无法解决这个问题。

我有一个包含两个模块的多语言应用程序:default 和 admin。语言选择工作正常(在 Controller routeShutdown 插件中),但我在配置路由器时遇到了一些问题:

我想让这些 URL 工作:

/
/controller
/controller/action
/action (default controller)
/controller/param (default action)
/admin
/admin/admin-controller
/admin/admin-controller/action

并使用语言选择器它将是:
/en
/en/controller
/en/controller/action
/en/action (default controller)
/en/controller/param (default action)
/en/admin/admin-controller
/en/admin/admin-controller/action

我将此添加到我的引导文件(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'));

为了检查路由器如何解析 URL,我在 routeShutdown 插件中添加了一个 var_dump:

进入 /zh ,我得到:
array
'lang' => string 'en' (length=2)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
'module' => string 'default' (length=7)

没关系。但是当我进入 /zh/controller1 我得到:
array
'lang' => string 'en' (length=2)
'module' => string 'controller1' (length=8)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)

它将模块设置为“controller1”。如何告诉路由器为模块设置默认值?对于像/en/controller/param 这样的 URL? (将模块和操作设置为默认值)

最佳答案

恐怕您需要重新考虑一下您的 URL 方案,或者更改您的路由设置方式,因为您遇到了 ZF 路由工作方式的两个限制。

首先是路由器不知道什么是或不是有效的模块、 Controller 或 Action ;它所做的只是将 URL 中的字符串与路由中的变量进行匹配。它通过以相反的顺序连续检查每条路由,直到找到匹配项来做到这一点。当您点击 /en/controller ,它首先检查您的/:lang路线,不匹配。然后检查 /:lang/:module ,这将匹配,因为 /:lang/:module将匹配/anything/anything 除非您另有说明。

考虑到这一点,您将无法同时拥有两者:

/en/controller
/en/action

除非您设置一些限制,如 /en/foo 之类的 URL将始终与您最后定义的两者中的任何一个匹配。

如果您有相当少量不经常更改的操作/ Controller ,解决此问题的最简单方法是为两条 route 的第二条硬编码一些可能的值,例如:
$router->addRoute('langmod', new Zend_Controller_Router_Route(
'/:lang/:module',
array(
'lang' => ':lang',
'action' => 'index',
'controller' => 'index'
),
array(
'module' => '(foo|bar|something)'
)
));

用有效的模块名称替换 foo、bar 等。现在当你点击 /en/controller1它不会匹配这个路由,因为 controller1 不匹配为 :module 变量定义的正则表达式模式。然后你需要一个单独的 /:lang/:controller路由(或可能 /:lang/:controller/:action )改为匹配。

您询问了如何为某些变量设置默认值。实际上,您已经在一些 route 使用该操作执行此操作,但是对于 Controller /模块而言,它不会完全按照您希望的方式工作。如果我们采用您的 langmodcontroller 路线并将其更改为:
$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
'/:lang/:module/:controller',
array(
'lang' => ':lang',
'controller' => 'index'
'action' => 'index'
)
));

现在有一个 Controller 变量的默认值。如果我们假装这是唯一的路由,请求 /en/blog现在将与之匹配并将请求参数设置为 lang = en、module = blog、controller = index、action = index。 /en/blog/index/foo也会匹配这条路线,并且会给你 module = blog,controller = index,action = foo。但请注意,即使 controller = index 您仍然需要在 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)

这会给你这样的 URL:
/en
/en/controller
/en/controller/action
/en/action
/en/controller/param
/en/admin/controller
/en/admin/controller/action

这几乎就是你所追求的。

ZF中的路由功能非常强大,你只需要知道它的怪癖。

关于zend-framework - Zend 路由问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9436653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com