如何使用getServiceLocator()获取模型中的适配器?
我正在学习ZF2。如何使用getServiceLocator()获取模型中的适配器?
我可以使用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');
在模型中获取适配器?
如果您使用的是最新的Zend Framework版本,则不能在控制器类中使用getServiceLocator
方法,因为ServiceLocatorAwareInterface
和ServiceManagerAwareInterface
都被删除。
所以这行:你也许在你的控制器类预期
$sm = $this->getServiceLocator();
将无法工作。
您还可以在the migration guide阅读更多的这种变化:
以下接口,特点和类被拆除:
- ...
- 的Zend \的ServiceManager \ ServiceLocatorAwareInterface
- Zend \ ServiceManager \ ServiceLocatorAwareTrait
- 的Zend \的ServiceManager \ ServiceManagerAwareInterface
的ServiceLocatorAware和ServiceManagerAware接口和性状进行了下V2太经常被滥用,并且代表的服务管理器组件的用途的对立面;依赖关系应该直接注入,并且容器不应该由对象组成。
您将需要重构您的服务,可能最好的方法是创建一个服务工厂,在其中注入您的依赖关系。
检查this blog post(章节工厂)关于如何建立工厂的更多细节。
您将需要在模型创建时将适配器注入到模型中,例如使用工厂。
例如在你的配置:
'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');
这将调用工厂,并带回该模型的完整与适配器。
然后,您可以使用相同的方法将模型注入到需要的任何控制器或服务类中。正如前面的帖子所说,尽量避免直接将服务定位器/服务管理器注入到对象中,而是使用它从工厂类中添加需要的项目(适配器/映射器等)。