Zend framework 2 多语言配置
Zend Framework 2 默认支持国际化I18n,直接在Zend Studio里建的工程,也是默认就开启了多语言配置,只需要更改 ‘locale’ => ‘en_US’ 就可以修改网站显示language目录下面的.mo里的语言。但是没有找到语言切换相关的配置,比如根据浏览器的语言自动切换语言显示,或者根据用户指定的语言显示…
配置 module.config.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
//此处省略N行代码 'service_manager' => array( 'allow_override' => true, 'factories' => array( 'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory' ), 'aliases' => array( 'translator' => 'MvcTranslator' ) ), 'translator' => array( 'locale' => 'en_US', 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo' ) ), // 由于一种语言,有多种表现形式,日语可以是ja,ja-jp,简单中文zh,zh-CN,这里归纳一下 // abbr,与框架Library同级resource下语言目录名称,看起来像缩写 // include,语言包含的形式 // 此处我的网站使用三种语言:zh_CN, en_US, zh_TW,有更多语言往后面加 'correspond' => array( 'zh_CN' => array( 'abbr' => 'zh', 'include' => array( 'zh', 'zh-CN' ) ), 'en_US' => array( 'abbr' => 'en', 'include' => array( 'en', 'en-US' ) ), 'zh_TW' => array( 'abbr' => 'zh_TW', 'include' => array( 'zh-TW' ) ) ) ), //此处省略N行代码 |
语言初始化在框架加载的时就可以做了,所以可以直接在 Module.php bootstrap里写。这里有一个优先级的问题:
语言可以通过三种途径方式获得:
- 用户主动设置时
- 用户主动设置过,已保存在Session中
- 用户未主动设置,Session中也未保存语言,此时可从 Http协议头里拿到 Accept-Language 的值作为首选语言项
优先级别最高的是用户主动设置,其次是Session中已保存的语言,当前两者都没有的时候才选择 协议头里的值作为语言参考项。而当这三项都拿不到的时候,则会使用默认配置 local 填写的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
namespace Application; use Zend\Mvc\ModuleRouteListener; use Zend\Mvc\MvcEvent; use Zend\Session\Container; use Zend\Session\SessionManager; use Zend\Session\Config\SessionConfig; class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); //调用 multiLanguageSupport 设置语言 $this->multiLanguageSupport($e); } public function multiLanguageSupport(MvcEvent $e) { // 获取MvcTranslator,是关键一步 $MvcTranslator = $e->getApplication() ->getServiceManager() ->get('MvcTranslator'); /** * Get http request header * 获取头部信息,便于获取 Accept-Language */ $headers = $e->getApplication() ->getRequest() ->getHeaders(); /** * Get correnpond from module.config.php * 获得配置中的 correspond,也就是我们允许切换的语言 */ $correspond = $e->getApplication() ->getServiceManager() ->get('config'); $correspond = $correspond['translator']['correspond']; /** * Session Language, Priority: 2 * 设置一个Session容器,在设置了语言后,将语言保存在Session里。 */ $SessionConfig = new SessionConfig(); $sessionTimeout = 60 * 60 * 24 * 365; $SessionConfig->setOptions(array( 'gc_maxlifetime' => $sessionTimeout, //php gc 回收时间 'remember_me_seconds' => $sessionTimeout, // 记住时间 'cache_expire' => $sessionTimeout, // 缓存时间 'cookie_lifetime' => $sessionTimeout //发送到浏览器的过期时间 )); //获取Session容器里的语言,优先级介于浏览器和用户设置之间 $Container = new Container('ModuleLanguageSetting', new SessionManager($SessionConfig)); $sessionLanguage = $Container->offsetGet('lang'); /** * Browser Language, Priority: 1 min * 获取浏览器的语言,优先级最小 */ $FiledValParts = array(); if ($headers->has('Accept-Language')) { $FiledValParts = $headers->get('Accept-Language')->getPrioritized(); } /** * Url Language, Priority: 3 max * 在Url中获取?Language=zh-CN,这个优先级最高,因为他可能是用户主动设置的语言 */ $requestLanguage = $e->getRequest()->getQuery('language'); /** * Setting language * 通过各种优先级的判断得出最后需要使用的语言和语言缩写 */ $resultLanguage = ''; $resultLanguageAbbr = ''; if (! empty($requestLanguage) || ! empty($sessionLanguage)) { if (! empty($requestLanguage)) { $readyLanguge = $requestLanguage; } elseif (! empty($sessionLanguage)) { $readyLanguge = $sessionLanguage; } foreach ($correspond as $lang => $langItem) { if (in_array($readyLanguge, $langItem['include'])) { $resultLanguage = $lang; $resultLanguageAbbr = $langItem['abbr']; if (! empty($requestLanguage)) $Container->offsetSet('lang', $requestLanguage); break; } } } elseif (! empty($FiledValParts)) { $FiledValParts = $headers->get('Accept-Language')->getPrioritized(); if (count($FiledValParts) > 0) { foreach ($FiledValParts as $part) { foreach ($correspond as $lang => $langItem) { $browserLanguage = $part->getLanguage(); if (in_array($browserLanguage, $langItem['include'])) { $resultLanguage = $lang; $resultLanguageAbbr = $langItem['abbr']; break 2; } } } } } if (! empty($resultLanguage) && ! empty($resultLanguageAbbr)) { // 设置语言 $MvcTranslator->setLocale($resultLanguage); // 设置要加载的其它的语言文件 $MvcTranslator->addTranslationFile('phpArray', __DIR__ . '/../../vendor/zendframework/zendframework/resources/languages/' . $resultLanguageAbbr . '/Zend_Validate.php', 'default', $resultLanguage); } \Zend\Validator\AbstractValidator::setDefaultTranslator($MvcTranslator); } //....此处省略N行代码 } |
当这里配置完成,在URL上使用?language=zh-CN或者 ?language=zh-TW即可切换语言。切换失败也就是传入参数无法与配置里的匹配时,默认使用配置 local 的值
转载自:https://www.fourfire.cc/zend-framework-2-%E5%A4%9A%E8%AF%AD%E8%A8%80%E9%85%8D%E7%BD%AE/