Каков наилучший вариант использования языкового коммутатора в моей системе ZF2?

Я разработал небольшую систему доктрин ZF2 для одного из моих клиентов. Пока все хорошо, но они требуют системы на двух языках.

Я могу установить язык по умолчанию как english или another language из моего module/Application/config/module.config.php

 'translator' => array( 'locale' => 'en_US', 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo', ), ), ), 

И я также могу использовать этот метод для установки значения по умолчанию в module.php

 public function onBootstrap(MvcEvent $e) { $application = $e->getApplication(); $serviceManager = $application->getServiceManager(); // Just a call to the translator, nothing special! $serviceManager->get('translator'); $this->initTranslator($e); // Etc, more of your bootstrap function. } protected function initTranslator(MvcEvent $event) { $serviceManager = $event->getApplication()->getServiceManager(); // Zend\Session\Container $session = New Container('language'); $translator = $serviceManager->get('translator'); $translator ->setLocale($session->language) ->setFallbackLocale('zh_CN') ; } 

Это хорошо, теперь моя система показывает язык по умолчанию как китайский. Тем не менее, я хотел бы дать возможность пользователям выбирать.

Как мне это сделать?

Я нашел эту ссылку, но я не мог заставить ее работать.

Когда я добавляю следующую функцию в Application/IndexController.php она ничего не делает вместо http://myurl.com/changeLocal throw 404 error . Нужно ли добавлять что-либо в module.config.php ?

 public function changeLocaleAction() { // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); $language = $request->getPost()->language; $config = $this->serviceLocator->get('config'); if (isset($config['locale']['available'][$language])) { $session->language = $language; $this->serviceLocator->get('translator')->setLocale($session->language); } } 

    Вам нужны средства для вызова changeLocaleAction . Маршрут, связанный с этим действием контроллера, действительно будет самым простым:

     'language' => array( 'type' => 'literal', 'options' => array( 'route' => '/language', 'defaults' => array( 'controller' => `Application\Controller\IndexController`, 'action' => 'changeLocaleAction' ) ) ), 

    Вам нужно поймать значение post для языка в вашем методе:

     $request->getPost('language'); 

    Или в вашем контролере, используя плагин params:

     $this->params()->fromPost('language'); 

    поэтому это указывает на то, что пользователь 'zh_CN' форму с language полем, которое содержит предпочтительный языковой параметр, например, 'zh_CN' или 'en_US' в качестве значения.

    Вы можете упростить клиентскую сторону, поскольку у вас есть только два варианта языка. Вы можете просто использовать кнопку, которая переключает язык и публикует другое значение:

    Поэтому, если в настоящее время язык является 'en_US' вы 'zh_CN' и наоборот.

    После долгой битвы, вот как я это достиг. Особая благодарность @Kwido и @Wilt за отправку меня в правильном направлении (я проголосовал за них обоих).

    Применение / Config / module.config.php

     return array( 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController' ), ), 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), ), 'language' => array( 'type' => 'Segment', 'options' => array( //'route' => '/[:language]', 'route' => '/en', 'constraints' => array( 'language' => 'en', ), 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'changeLocaleEnglish' ) ) ), 'languageChinese' => array( 'type' => 'Segment', 'options' => array( //'route' => '/[:language]', 'route' => '/cn', 'constraints' => array( 'language' => 'cn', ), 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'changeLocaleChinese' ) ) ), //// // other stuff //////////// like child routes etc ), ), 'service_manager' => array( 'abstract_factories' => array( 'Zend\Cache\Service\StorageCacheAbstractServiceFactory', 'Zend\Log\LoggerAbstractServiceFactory', ), 'factories' => array( 'translator' => 'Zend\Mvc\Service\TranslatorServiceFactory', ), ), 'translator' => array( 'locale' => 'zh_CN', //default is english which is set in module.php 'translation_file_patterns' => array( array( 'type' => 'gettext', 'base_dir' => __DIR__ . '/../language', 'pattern' => '%s.mo', ), ), ), 'view_helpers' => array( 'invokables'=> array( 'PaginationHelper' => 'Application\View\Helper\PaginationHelper' ) ), 'view_manager' => array( //....... view stuff ), // Placeholder for console routes 'console' => array( 'router' => array( 'routes' => array( ), ), ), ); 

    Применение / module.php

     public function onBootstrap(MvcEvent $e) { $application = $e->getApplication(); $serviceManager = $application->getServiceManager(); // Just a call to the translator, nothing special! $serviceManager->get('translator'); $this->initTranslator($e); } protected function initTranslator(MvcEvent $event) { $serviceManager = $event->getApplication()->getServiceManager(); // use Zend\Session\Container add this to top $session = New Container('language'); $translator = $serviceManager->get('translator'); if($session['language'] != 'zh_CN'){ //if session doesn't have zh_CN then set it as english $translator ->setLocale($session->language) ->setFallbackLocale('en_US') ; } } 

    теперь в приложении / src / Application / Controller / IndexController.php Я добавил два действия, чтобы поймать сессию и установить язык:

     public function changeLocaleChineseAction() { $result = new ViewModel(); $result->setTerminal(true); $response = $this->getResponse(); // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); $request = $this->getRequest(); $config = $this->serviceLocator->get('config'); $language = $config['translator']['locale']; //default locale from Application/config/module.config.php if (isset($config['translator']['locale'])) { $session->language = $language; $this->serviceLocator->get('translator')->setLocale('zh_CN') ->setFallbackLocale('zh_CN') ; } return $this->redirect()->toRoute('home'); } public function changeLocaleEnglishAction() { // New Container will get he Language Session if the SessionManager already knows the language session. $session = new Container('language'); //just clear the language session $session->getManager()->getStorage()->clear('language'); $language = 'en_US'; //set new language $request = $this->getRequest(); $config = $this->serviceLocator->get('config'); $session->language = $language; $this->serviceLocator->get('translator')->setLocale('en_US') ->setFallbackLocale('en_US') ; return $this->redirect()->toRoute('home'); } 

    Теперь просто добавьте ссылку в layout.phtml чтобы переключиться на язык:

     <a href="<?php echo $this->url('home')."cn";?>"><?php echo $this->translate("Chinese");?></a> <a href="<?php echo $this->url('home')."en";?>"><?php echo $this->translate("English");?></a> 

    Надеюсь, это поможет другим в будущем.