我正在学习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');
在模型中获取适配器?
答案 0 :(得分: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');
这将调用工厂并使用适配器恢复模型。
然后,您将使用相同类型的方法将模型注入任何需要它的控制器或服务类。如前一篇文章所述,尝试避免将服务定位器/服务管理器直接注入到对象中,而是使用它来从Factory类等中添加所需的项目(适配器/映射器等)。
答案 1 :(得分:0)
如果您使用的是最新的Zend Framework版本,则无法在控制器类中使用getServiceLocator
方法,因为ServiceLocatorAwareInterface
和ServiceManagerAwareInterface
都被删除了。
所以这一行:
$sm = $this->getServiceLocator();
在你的控制器课程中,你可能会像预期的那样工作。
您还可以在the migration guide中了解有关此更改的更多信息:
删除了以下接口,特征和类:
- ...
- 的Zend \的ServiceManager \ ServiceLocatorAwareInterface
- 的Zend \的ServiceManager \ ServiceLocatorAwareTrait
- 的Zend \的ServiceManager \ ServiceManagerAwareInterface
ServiceLocatorAware和ServiceManagerAware接口和特性在v2下经常被滥用,并且代表了Service Manager组件目的的对立面;应该直接注入依赖项,并且容器永远不应该由对象组成。
您需要重构您的服务,可能最好的方法是创建一个注入依赖项的服务工厂。
同时查看this blog post(章工厂),详细了解如何建立工厂。