Zend框架2在模型中的翻译

时间:2013-06-04 10:50:13

标签: php zend-framework2 zend-translate

如何在模型中获得翻译?

在内部视图中,我们可以使用此代码获得翻译

$this->translate('Text')

在内部控制器中,我们可以使用此代码获取翻译器

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

$translator->translate("Text") ;

但如何在模型中获得翻译?

我尝试了很多方法来获取模型中的服务定位器 其中2个

1)使用MVC事件

    $e=new MvcEvent();
    $sm=$e->getApplication()->getServiceManager();
    $this->translator = $sm->get('translator');

如果我pring $ sm它显示为null。但它在Model.php onBootstrap

中工作正常

2)创建了一个实现 ServiceLocatorAwareInterface 的模型 SomeModel.php

    <?php

namespace Web\Model;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class SomeModel implements ServiceLocatorAwareInterface
{
    protected $services;

    public function setServiceLocator(ServiceLocatorInterface $locator)
    {
        $this->services = $locator;
    }

    public function getServiceLocator()
    {
        return $this->services;
    }
}

并在我的模型中使用

        $sl = new SomeModel();
        $sm=$sl->getServiceManager();
        var_dump($sm); exit;
        $this->translator = $sm->get('translator');

这也是打印空。

2 个答案:

答案 0 :(得分:3)

如果您的模型中不需要servicemanager实例,只需将translator实例注入其中即可。

例如:

// Your model's constructor

class MyModel {
  // Use the trait if your php version >= 5.4.0
  use \Zend\I18n\Translator\TranslatorAwareTrait;

  public function __construct( $translator )
  {
     $this->setTranslator( $translator ); 
  }

  public function modelMethodWhichNeedsToUseTranslator()
  {
    // ...
    $text = $this->getTranslator()->translate('lorem ipsum');
    // ...
  }
}

在服务或控制器级别第一次创建模型时

class someClass implements ServiceLocatorAwareInterface {
    public function theMethodWhichCreatesYourModelInstance()
    {
    // ...
    $sm = $this->getServiceLocator();
    $model = new \Namespace\MyModel( $sm->get('translator') )
    // ...
    }
}

如果您需要在多个方法/类上实例化您的模型(new MyModel();),请考虑为其编写工厂。

以下是Ralph Schindler关于Dependency Injection and PHP的一篇很好的文章,对这种方法有更详细的评论。

答案 1 :(得分:0)

对于ModelServiceLocatorAware,您不仅需要实现接口,还需要使模型成为服务管理器的服务,并从那里获取模型。

将您的模型添加到服务管理器,因为它似乎不需要任何构造函数参数,它是可调用的,因此您可以将它添加到服务管理器配置中的invokables数组中。您可以使用getServiceConfig()类中的Module方法...

来实现
class Module
{
    public function getServiceConfig()
    {
        return array(
            'invokables' => array(
                'SomeModel' => 'Fully\Qualified\ClassName\To\SomeModel',
            ),
        );
    }
}

然后,不是调用new关键字来创建模型实例,而是从服务管理器获取它,例如,通过在控制器操作中调用getServiceLocator()方法...

public function fooAction()
{
     $sm = $this->getServiceLocator();
     $model = $sm->get('SomeModel');
}

当从服务管理器获取模型时,服务initializer将查看它是否实现ServiceLocatorAwareInterface并自动调用setServiceLocator(),如果是,则传递一个实例服务经理。