Zend Framework 2: Как установить глобальную локаль?
Я должен динамически менять локаль в зависимости от того, какой язык хочет пользователь.
Я могу установить локаль в Application/Module.php следующим образом:
public function onBootstrap(MvcEvent $e)
{
$translator = $e->getApplication()->getServiceManager()->get('translator');
$translator->setLocale('hu_HU');
}
Но как я могу сделать это в контроллере, если я хочу изменить язык? Я пробовал это, но после этого я могу изменить локаль только для этого одного запроса, а не глобальный.
$translator = $this->getServiceLocator()->get('translator');
$translator->setLocale('srb_SRB');
4 ответа
Установите локаль по умолчанию на уровне конфигурации! Смотрите № 61 изmodule.config.php
из прикладного модуля ZendSkeletonApplications
'translator' => array(
'locale' => 'en_US',
)
Я была такая же проблема. В моем модуле входа пользователя я зарегистрировался для MvcEvent при загрузке:
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Session\SessionManager;
use Zend\Session\Container as SessionContainer;
use \Zend\I18n\Translator\TranslatorInterface;
...
public function onBootstrap(MvcEvent $event)
{
// Get event manager.
$eventManager = $event->getApplication()->getEventManager();
$sharedEventManager = $eventManager->getSharedManager();
// Register the event listener method.
$sharedEventManager->attach(AbstractActionController::class,
MvcEvent::EVENT_DISPATCH, [$this, 'onDispatch'], 100);
}
Затем, когда происходит это событие, я устанавливаю локаль на основе информации из URL:
public function onDispatch(MvcEvent $event)
{
$servicemanager = $event->getApplication()->getServiceManager();
$lang = $event->getRouteMatch()->getParam('lang','jp-JP');
$translator = $servicemanager->get(TranslatorInterface::class);
if( $translator != null )
{
$translator->setLocale($lang);
}
...
В конце концов, это не делает глобальную локаль - она просто устанавливает ее для каждого запроса. Чистый эффект одинаков с точки зрения кода - т.е. мне не нужно устанавливать локаль на каждом контроллере.
Надеюсь, это поможет.
Эта работа для меня:
public function onBootstrap(MvcEvent $e)
{
$localeFromHttp = \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (false === stripos($localeFromHttp, '-')) {
$locale = $localeFromHttp . '_' . strtoupper($localeFromHttp);
$e->getApplication()
->getServiceManager()
->get('MvcTranslator')
->setLocale($locale);
}
else {
$e->getApplication()->getServiceManager()->get('MvcTranslator')->setFallbackLocale('en_US');
}
}
And my modal.config.php:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
'text_domain' => __NAMESPACE__,
),
),
),
В файле modal.config я не думаю, что требуется следующее, так как вы использовали псевдоним MvcTranslator для переводчика.
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
В ZF2 локаль устанавливается всегда по запросу. Вы можете сделать это при начальной загрузке:
$translator = $event->getApplication()->getServiceManager()->get('translator');
$translator->setLocale($locale);
$translator->addTranslationFile(
'phpArray', DATA_PATH . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . $locale . '.php', 'default', $locale
);
а затем в контроллере, если вы хотите изменить:
$translator = $this->getServicelocator()->get('translator');
$translator->setLocale($locale);
если вы измените выбранную локаль, вам нужно снова добавить путь к файлу перевода, чтобы он работал