【问题标题】:Zend framework 2 translator in modelZend framework 2 模型中的翻译器
【发布时间】:2013-06-04 10:50:13
【问题描述】:

如何在模型中获取翻译器?

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

$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 它显示为空。但它在 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');

这也是打印 null。

【问题讨论】:

    标签: php zend-framework2 zend-translate


    【解决方案1】:

    如果您的模型中不需要 servicemanager 实例,只需将翻译器实例注入它即可。

    例如:

    // 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 的精彩文章,了解有关此方法的更多详细信息。

    【讨论】:

      【解决方案2】:

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

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

      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(),将服务管理器的实例传递给它。

      【讨论】:

      • 感谢您的回答,但您没有正确理解我的问题
      • 真的吗?我错过了什么?
      • 你能写出完全符合我的问题的代码吗
      • 我编写了解释如何在模型类中提供服务定位器的代码。完成此操作后,在SomeModel 中,您应该能够通过调用$this-&gt;getServiceLocator()-&gt;get('translator'); 获得翻译器。再说一遍,如果这不能回答你的问题,我错过了什么?
      猜你喜欢
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 2013-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多