在模型中获取服务
Get a service inside a model
我是 zend 2 的新手,我想实现几个模型,这些模型可以从 我想要的任何地方 访问,即从控制器和其他模型访问。
从控制器它已经可以工作了。但是我不知道如何在没有 getServiceLocator()
方法的模型中进行操作。此外,我无法从模型内部访问服务定位器来获取配置。
namespace Bsz\Services;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
class OpenUrl implements ServiceLocatorAwareInterface {
protected $serviceLocator;
public function __construct() {
$sm = $this->getServiceLocator();
$config = $sm->get('config');
var_dump($sm); //null
}
public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
来自 module.config.php
的片段
'service_manager' => [
'invokables' => [
'bsz\openurl' => 'Bsz\Services\OpenUrl',
]
],
这里是我的 Action,它已经有效了
public function indexAction() {
$OpenUrl = $this->getServiceLocator()->get('bsz\openurl');
//works, is an object of type bsz\openurl.
}
所以我的问题是:如何在本身用作服务的模型中正确地获取服务管理器?如何在其他模型中执行此操作?
我发现了很多这样的问题并尝试了很多,但仍然没有解决这个问题。也许 Zend 的版本差异? 我们使用 Zend 2.3.7。
我现在找到了第一个问题的答案:必须将 erviceManager 注入到模型中。这只能通过工厂来完成:
Factory.php
namespace Bsz\Services;
use Zend\ServiceManager\ServiceManager;
class Factory {
public static function getOpenUrl(ServiceManager $sm)
{
return new \Bsz\Services\OpenUrl($sm);
}
}
module.config.php
'service_manager' => [
'factories' => [
'bsz\openurl' => 'Bsz\Services\Factory::getOpenUrl',
]
],
但是如何从另一个没有 getServiceLocator
方法的模型中检索此服务?
OpenUrl
服务 取决于 它的配置。因此,配置是服务的 dependency。在没有配置的情况下创建服务是没有意义的。
您已将 bsz\openurl
服务注册为 'invokable' class。这意味着当您请求服务时,服务管理器将实例化 Bsz\Services\OpenUrl
class 而无需传入任何构造函数参数。这不是您想要的,您 需要 创建 class 后的配置。
向服务工厂注册服务
为了实现这个 ZF2 附带了它自己的工厂接口,Zend\ServiceManager\FactoryInterface
,我们的新工厂应该实现它。
namespace Bsz\Services;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class OpenUrlFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $this->getConfig($serviceLocator);
$service = new OpenUrl($config);
return $service;
}
protected function getConfig(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
if (! isset($config['open_url'])) {
throw new \RuntimeException('The service configuration key \'open_url\' could not be found');
}
return $config['open_url'];
}
}
现在我们可以更新 module.config.php
并将服务类型更改为工厂。
'service_manager' => [
'factories' => [
'bsz\openurl' => 'Bsz\Services\OpenUrlFactory',
],
],
在此之后,如果 SomeService
depends on OpenUrl
那么您可以使用新的 SomeServiceFactory
重复工厂过程,其中依赖项是 OpenUrl
.
我是 zend 2 的新手,我想实现几个模型,这些模型可以从 我想要的任何地方 访问,即从控制器和其他模型访问。
从控制器它已经可以工作了。但是我不知道如何在没有 getServiceLocator()
方法的模型中进行操作。此外,我无法从模型内部访问服务定位器来获取配置。
namespace Bsz\Services;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
class OpenUrl implements ServiceLocatorAwareInterface {
protected $serviceLocator;
public function __construct() {
$sm = $this->getServiceLocator();
$config = $sm->get('config');
var_dump($sm); //null
}
public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
来自 module.config.php
'service_manager' => [
'invokables' => [
'bsz\openurl' => 'Bsz\Services\OpenUrl',
]
],
这里是我的 Action,它已经有效了
public function indexAction() {
$OpenUrl = $this->getServiceLocator()->get('bsz\openurl');
//works, is an object of type bsz\openurl.
}
所以我的问题是:如何在本身用作服务的模型中正确地获取服务管理器?如何在其他模型中执行此操作?
我发现了很多这样的问题并尝试了很多,但仍然没有解决这个问题。也许 Zend 的版本差异? 我们使用 Zend 2.3.7。
我现在找到了第一个问题的答案:必须将 erviceManager 注入到模型中。这只能通过工厂来完成:
Factory.php
namespace Bsz\Services;
use Zend\ServiceManager\ServiceManager;
class Factory {
public static function getOpenUrl(ServiceManager $sm)
{
return new \Bsz\Services\OpenUrl($sm);
}
}
module.config.php
'service_manager' => [
'factories' => [
'bsz\openurl' => 'Bsz\Services\Factory::getOpenUrl',
]
],
但是如何从另一个没有 getServiceLocator
方法的模型中检索此服务?
OpenUrl
服务 取决于 它的配置。因此,配置是服务的 dependency。在没有配置的情况下创建服务是没有意义的。
您已将 bsz\openurl
服务注册为 'invokable' class。这意味着当您请求服务时,服务管理器将实例化 Bsz\Services\OpenUrl
class 而无需传入任何构造函数参数。这不是您想要的,您 需要 创建 class 后的配置。
向服务工厂注册服务
为了实现这个 ZF2 附带了它自己的工厂接口,Zend\ServiceManager\FactoryInterface
,我们的新工厂应该实现它。
namespace Bsz\Services;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class OpenUrlFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $this->getConfig($serviceLocator);
$service = new OpenUrl($config);
return $service;
}
protected function getConfig(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
if (! isset($config['open_url'])) {
throw new \RuntimeException('The service configuration key \'open_url\' could not be found');
}
return $config['open_url'];
}
}
现在我们可以更新 module.config.php
并将服务类型更改为工厂。
'service_manager' => [
'factories' => [
'bsz\openurl' => 'Bsz\Services\OpenUrlFactory',
],
],
在此之后,如果 SomeService
depends on OpenUrl
那么您可以使用新的 SomeServiceFactory
重复工厂过程,其中依赖项是 OpenUrl
.