ZF2在控制器中使用翻译器

问题描述:

对于URL重定向,我需要在控制器中翻译某些东西。ZF2在控制器中使用翻译器

如何访问$ this-> translate();在控制器中?

谢谢! 尼克

翻译通过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')来翻译字符串。

+0

最新版本的ZF2将翻译器的关键字更改为“MVCTranslator”。 – MKroeders

+0

不适用于我。我有以下错误: 可捕获的致命错误:参数1传递给Application \ Controller \ CorrespondenciasController :: __ construct()必须是Zend \ I18n \ Translator \ Translator的实例,没有给出,在/ home/inhotim中调用/Trabalho/0-OPE/scape/Products/ oo/Web/landscape /vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php 207行,并在/ home/inhotim/Trabalho/0-OPE/scape中定义/Produção/Web/scape/module/Application/src/Application/Controller/CorrespondenciasController.phpon line 141 –

+0

@GustavoGonçalves这意味着你的工厂不工作。检查我的答案中的第一个代码块。 –

我想有一个最好的方式做到这一点:

$translator = $this->getServiceLocator()->get('translator'); 
$translator->translate('__your_key'); 

如果您想使用控制器译者就像在看,就是这样:

$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。因此,您无法获取配置并通过TranslatorServiceFactory创建对象Translate

取而代之的是,您可以通过输入$serviceLocator->getController()来访问分配给已为其调用助手的控制器的ServiceLocator

当然,在$serviceLocator方法createService传递是Zend\Mvc\Controller\PluginManager实例。

为什么代理? 通过插件工厂返回的对象必须实现

Zend\Mvc\Controller\Plugin\PluginInterface 

这是在

Zend\Mvc\Controller\Plugin\AbstractPlugin 

抽象实现,所以我们创建的代理对象从我们的插件到Translate对象的所有呼叫。

希望它有帮助!

我在我自己的博客上发表了一篇文章。

+0

这看起来很完美,同时也是集中的。谢谢@Athlan! – smozgur

+0

Your s解决方案看起来不错!谢谢!而你来自波兰:) –

+0

不适用于我?缺少什么? 1-我在应用程序模块下的model.config.php中注册插件。 2-我在Application \ Controller \ Plugin中创建了translater.class。 4-在另一个控制器中调用$ this-> translate('Hello',__ NAMESPACE __,$ mylocale)。 – Oskar

你可以这样来做:

$translate = $this->getServiceLocator()->get('viewhelpermanager')->get('translate'); 

$translator = $this->getServiceManager()->get('MVCTranslator'); 

在我的情况下完美的作品这个解决方案:

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 
     */ 
    } 

} 

可调用是可以不带任何参数来构建一个类。由于我们的MyModule \ Controller \ FooController现在有一个必需的参数,我们需要改变它。 A 工厂是创建另一个类的实例的类。我们现在将为我们的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 */) 
); 

让我们实现我们的工厂类,这在创建一个新的文件夹\模块\ MyModule中的\ src \ MyModule的\厂和所谓的新文件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的内。为此,我们将需要覆盖默认__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'); 
     ... 
    } 
} 

在我的情况下正常工作!