对于网址重定向,我需要在控制器中翻译一些内容。
如何访问$ this-> translate();在控制器?
谢谢! 尼克
答案 0 :(得分:17)
翻译是通过Translator
完成的。翻译器是一个对象,例如在视图助手中注入,因此如果您调用该视图助手,它将使用翻译器来翻译您的字符串。对于这个答案,我假设您已配置翻译just the same as the skeleton application。
最好的方法是使用工厂将其作为依赖项注入控制器。控制器配置:
'controllers' => array(
'factories' => array(
'my-controller' => function($sm) {
$translator = $sm->getServiceLocator()->get('translator');
$controller = new MyModule\Controller\FooController($translator);
}
)
)
控制器本身:
namespace MyModule;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\I18n\Translator\Translator;
class FooController extends AbstractActionController
{
protected $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
}
另一种方法是在您的操作中从服务管理器中提取翻译器,但这不太灵活,不太可测试且难以维护:
public function fooAction()
{
$translator = $this->getServiceManager()->get('translator');
}
在这两种情况下,您都可以使用$translator->translate('foo bar baz')
翻译字符串。
答案 1 :(得分:11)
如果你想在控制器中使用翻译器,就像那样:
$this->translate('Hello')
而不是丑陋:
$this->getServiceLocator()->get('translator')->translate('Hello')
您也可以为控制器编写翻译插件,就像查看助手Zend\I18n\View\Helper\Translate
一样。
当然,您可以使用相同的签名调用插件:
__invoke($message, $textDomain = null, $locale = null)
只需注册:
'controller_plugins' => array(
'factories' => array(
'translate' => 'Application\Controller\Plugin\Translate',
),
),
并编写插件:
<?php
namespace Application\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\I18n\Translator\Translator;
class Translate implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceLocator = $serviceLocator->getController()->getServiceLocator();
$serviceFactory = new TranslatorServiceFactory();
$translator = $serviceFactory->createService($serviceLocator);
return new TranslatorProxy($translator);
}
}
final class TranslatorProxy extends AbstractPlugin
{
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function __invoke($message, $textDomain = 'default', $locale = null)
{
return $this->translator->translate($message, $textDomain, $locale);
}
public function __call($method, $args)
{
return call_user_func_array([$this->translator, $method], $args);
}
public static function __callstatic($method, $args)
{
return call_user_func_array([$this->translator, $method], $args);
}
}
如何运作?
你看,传递的ServiceLocator
createService(ServiceLocatorInterface $serviceLocator)
配置空间controller_plugins
中的工厂无法访问控制器中Config
中的ServiceLocator
服务。因此,您无法通过Translate
获取配置并创建TranslatorServiceFactory
对象。
通过键入ServiceLocator
,您可以访问分配给已调用我们帮助程序的控制器的$serviceLocator->getController()
。
当然,$serviceLocator
方法中传递的createService
是Zend\Mvc\Controller\PluginManager
的实例。
为什么要代理? 通过插件工厂返回的对象必须实现
Zend\Mvc\Controller\Plugin\PluginInterface
在
中抽象实现Zend\Mvc\Controller\Plugin\AbstractPlugin
所以我们创建了代理对象来将我们插件中的所有调用转发到Translate
对象。
希望它有所帮助!
我在自己的博客上发表了一篇文章。
答案 2 :(得分:1)
我想这是最好的方法:
$translator = $this->getServiceLocator()->get('translator');
$translator->translate('__your_key');
答案 3 :(得分:0)
$translator = $this->getServiceManager()->get('MVCTranslator');
答案 4 :(得分:0)
在我的案例中完美地解决了这个问题:
namespace MyNS;
class MyCtrlr
{
protected $translator;
public function getTranslator()
{
if (!$this->translator)
{
$sm = $this->getServiceLocator();
$this->translator = $sm->get('translator');
}
return $this->translator;
}
public function myAction()
{
$sTrHello = $this->getTranslator()->translate('Hello');
/*
* More code here
*/
}
}
答案 5 :(得分:0)
invokable 是一个可以在没有任何参数的情况下构造的类。由于我们的 MyModule \ Controller \ FooController 现在有一个必需的参数,我们需要更改它。 factory 是一个创建另一个类实例的类。我们现在为 FooController 创建一个。让我们像这样修改我们的module.config.php文件:
return array(
'view_manager' => array( /** ViewManager Config */ ),
'controllers' => array(
'invokables' => array(
//'MyModule\Controller\Foo' => 'MyModule\Controller\FooController'
),
'factories' => array(
'MyModule\Controller\Foo' => 'MyModule\Factory\FooControllerFactory',
)
),
'router' => array( /** Router Config */ )
);
让我们实现我们的工厂类,为此在 \ module \ MyModule \ src \ MyModule \ Factory 中创建一个新文件夹,并在 FooControllerFactory.php 中创建一个新文件:
<?php
namespace MyModule\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use MyModule\Controller\FooController;
class FooControllerFactory implements FactoryInterface
{
public function __construct()
{}
/**
* Create service
*
* @param ServiceLocatorInterface $serviceLocator
*
* @return mixed
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$realServiceLocator = $serviceLocator->getServiceLocator();
$translator = $realServiceLocator->get('translator');
return new FooController($translator);
}
}
现在让我们在 FooController 中使用 $ translator 。为此,我们需要覆盖默认的 __ contruct():
<?php
namespace MyModule\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\I18n\Translator;
class FooController extends AbstractActionController
{
protected $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function FooAction()
{
...
$msg = $this->translator->translate('Blah blah blah');
...
}
}
在我的情况下工作正常!!!
答案 6 :(得分:-1)
你可以这样做:
$translate = $this->getServiceLocator()->get('viewhelpermanager')->get('translate');