正确使用 zend 框架中的语言
我有一个带有两个模块(管理和公共)的 Zend 应用程序,对于公共,我有以下插件来解析我的友好 URL:
class Custom_Controller_Plugin_Initializer extends Zend_Controller_Plugin_Abstract {
protected $_front;
protected $_request;
public function __construct() {
$this->_front = Zend_Controller_Front::getInstance();
$this->_request = $this->_front->getRequest();
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
//checking if the url ends with "/"
$requestUri = $this->_request->getRequestUri();
$path = parse_url($requestUri, PHP_URL_PATH);
$query = parse_url($requestUri, PHP_URL_QUERY);
if (substr($path, -1) != '/') {
header('location: ' . $path . (isset($query) ? '/?' . $query : '/'));
die();
}
// exploding the uri to get the parts.
$uri = explode('/', substr($path, strlen(Zend_Controller_Front::getInstance()->getBaseUrl()) + 1));
$modelLanguage = new Model_Db_Language();
//checking if the first part is of 2 characters and if it's a registered language
if ($modelLanguage->checkLanguage($uri[0])) {
$language = $uri[0];
unset($uri[0]); //deleting the language from the uri.
$uri = array_values($uri);
} else {
$language = $modelLanguage->autoLanguage();
if (!$uri[0] == '' && (strlen($uri[0]) == 2)) {
$uri[0] = $language;
header('location: ' . Zend_Controller_Front::getInstance()->getBaseUrl() . '/' . implode($uri) . (isset($query) ? '/?' . $query : '/'));
die();
}
}
//remember that the language was deleted from the uri
$this->_request->setParam('requestUri', implode('/', $uri));
switch ($uri[0]) {
case 'search':
unset($uri[0]);
$this->_request->setParam('s', urldecode($uri[2]));
$this->_request->setModuleName('public');
$this->_request->setControllerName('content');
$this->_request->setActionName('search');
$this->_request->setParam('template', 'search');
break;
}
$this->_initTranslation($language);
$this->_initInterface();
}}
如果我想使用像 domain.com/en/about-us 这样的结构,它非常有用/mission/
因为我可以解析 url 并获取第一个参数“en”,然后找到与“about-us/mission”关联的页面,但是如果我想使用怎么办domain.com/en/user/profile/id/1/
,Zend 将“en”设置为控制器,将“user”设置为操作。如何正确设置 url 中的语言?
I have an Zend application with two modules (admin and public) and for public I have the following plugin to parse my friendly-url:
class Custom_Controller_Plugin_Initializer extends Zend_Controller_Plugin_Abstract {
protected $_front;
protected $_request;
public function __construct() {
$this->_front = Zend_Controller_Front::getInstance();
$this->_request = $this->_front->getRequest();
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
//checking if the url ends with "/"
$requestUri = $this->_request->getRequestUri();
$path = parse_url($requestUri, PHP_URL_PATH);
$query = parse_url($requestUri, PHP_URL_QUERY);
if (substr($path, -1) != '/') {
header('location: ' . $path . (isset($query) ? '/?' . $query : '/'));
die();
}
// exploding the uri to get the parts.
$uri = explode('/', substr($path, strlen(Zend_Controller_Front::getInstance()->getBaseUrl()) + 1));
$modelLanguage = new Model_Db_Language();
//checking if the first part is of 2 characters and if it's a registered language
if ($modelLanguage->checkLanguage($uri[0])) {
$language = $uri[0];
unset($uri[0]); //deleting the language from the uri.
$uri = array_values($uri);
} else {
$language = $modelLanguage->autoLanguage();
if (!$uri[0] == '' && (strlen($uri[0]) == 2)) {
$uri[0] = $language;
header('location: ' . Zend_Controller_Front::getInstance()->getBaseUrl() . '/' . implode($uri) . (isset($query) ? '/?' . $query : '/'));
die();
}
}
//remember that the language was deleted from the uri
$this->_request->setParam('requestUri', implode('/', $uri));
switch ($uri[0]) {
case 'search':
unset($uri[0]);
$this->_request->setParam('s', urldecode($uri[2]));
$this->_request->setModuleName('public');
$this->_request->setControllerName('content');
$this->_request->setActionName('search');
$this->_request->setParam('template', 'search');
break;
}
$this->_initTranslation($language);
$this->_initInterface();
}}
It is very usefull if I wanna use structure like domain.com/en/about-us/mision/
because I can parse the url and get the first param "en" and after that find the page associated to "about-us/mission" but what about if I wanna use domain.com/en/user/profile/id/1/
, Zend set "en" as controller and "user" as action. How can I set the language in the url and properly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个常见问题,所以让我概括和形式化一点。
假设您希望 Web 应用支持多种语言,并且有以下路由要求:
http://domain.com/language-code/controller-name/action-name
换句话说,您希望使用“语言代码”作为语言环境,并将前面的内容与默认的 Zend 模块路由结合起来。
假设您还想使用 Zend_Translate 根据语言环境提供翻译内容。
这是我使用的一些代码,经常“导出”到具有类似要求的项目中,我愿意进一步讨论。
相关配置项:
这里注册的插件语言:
操作助手:
查看 url 助手(覆盖默认的)。您必须根据您正在使用的新路由相应地编写您的网址:
希望这会有所帮助。
This is a common problem so let me generalize and formalize a little bit.
Let's say you want your web app to support multiple languages and you have the following routing requirements:
http://domain.com/language-code/controller-name/action-name
In other words you want to use "language-code" as locale and combine the previous with the default Zend module routing.
Let's assume you also want to use Zend_Translate to provide translated content according to the locale.
Here is some code I use and often "export" into project with similar requirements, I'm open to discuss further.
Relevant config items:
Here the registered Plugin language:
The action helper:
The view url helper (overriding default one). You have to write your urls accordingly with the new routing you are using:
Hope this help.
我想说你应该使用自定义路由器。这就是路由器的用途——从 URI 确定参数。现在你就让路由器无缘无故地工作。因为你随后改变了它的工作结果。
编写自定义路由器并不那么困难,我建议您应该这样做。你可以在那里写一些类似的东西:
并且你可以添加更多选项。此外,匹配可能会更快,因为您可以逻辑地构建 URI 分解。普通路由器是愚蠢的 - 它只是匹配 URI 来路由正则表达式,并在找到匹配时停止。
I'd say that you should use custom router. This is what router is for - determining parameters from URI. Now you just let the router do work for no reason. Because you then change the result of it's work.
Writing custom router is not that difficult and I would suggest you should do so. You can write there something like:
And you can add many more options. Also matching may be much faster because you can logically strucutre the URI decomposition. Normal router is dumb - it just matches URI to route regex and stops when match is found.