0

我正在学习ZF2。

我可以getServiceLocator()用来在模型中获取适配器吗?

/config/autoload/global.php

return array(
    'db' => array(
        'driver'         => 'Pdo',
        'dsn'            => 'mysql:dbname=zf2tutorial;host=localhost',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
        'aliases' => array(
            'db' => 'Zend\Db\Adapter\Adapter',
        ),
    ),
);

/config/autoload/local.php

return array(
    'db' => array(
        'username' => 'YOUR USERNAME HERE',
        'password' => 'YOUR PASSWORD HERE',
    ),
);

那么,我该如何使用:

$sm = $this->getServiceLocator();
$this->dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

在模型中获得适配器?

4

2 回答 2

2

您需要在创建模型时将适配器注入模型,例如使用工厂。

例如在您的配置中:

'service_manager' => array(
    'factories' => array( 
        'Application\Some\Model' => '\Application\Some\ModelFactory'
     )
)

然后,您将创建将适配器注入您的模型的工厂:

<?php
namespace Application\Some;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class ModelFactory implements FactoryInterface
{
   /**
     * Create service
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return mixed
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
         $adapter = $serviceLocator->get('Zend\Db\Adapter\Adapter');

         return new Model($adapter);
    }
}

在这种情况下,您显然需要让您的模型在其构造函数中接受适配器。

现在,无论您需要在哪里获取带有注入适配器的模型实例,您都可以调用:

$serviceLocator->get('Application\Some\Model');

这将调用工厂并带回带有适配器的模型。

然后,您将使用相同的方法将您的模型注入到任何需要它的控制器或服务类中。如上一篇文章所述,尽量避免将服务定位器/服务管理器直接注入到您的对象中,而是使用它从工厂类等中添加您需要的项目(适配器/映射器等)。

于 2016-12-15T09:46:14.477 回答
0

如果您使用的是最新的 Zend Framework 版本,您将无法getServiceLocator在控制器类中使用该方法,因为 theServiceLocatorAwareInterface和 theServiceManagerAwareInterface都已被删除。

所以这一行:

$sm = $this->getServiceLocator();

在控制器类中不会像您预期的那样工作。


您还可以在迁移指南中阅读有关此更改的更多信息:

删除了以下接口、特征和类:

  • ...
  • Zend\ServiceManager\ServiceLocatorAwareInterface
  • Zend\ServiceManager\ServiceLocatorAwareTrait
  • Zend\ServiceManager\ServiceManagerAwareInterface

ServiceLocatorAware 和 ServiceManagerAware 接口和特征在 v2 下经常被滥用,并且代表了 Service Manager 组件的目的的对立面;依赖项应该直接注入,容器永远不应该由对象组成。

您将需要重构您的服务,并且可能最好的方法是创建一个服务工厂,您可以在其中注入您的依赖项。

另请查看此博客文章工厂一章),了解有关如何建造工厂的更多详细信息。

于 2016-12-15T08:04:30.220 回答