我对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',
]
],
这是我的行动,已经有效了
public function indexAction() {
$OpenUrl = $this->getServiceLocator()->get('bsz\openurl');
//works, is an object of type bsz\openurl.
}
所以我的问题是:如何在一个本身用作服务的模型中正确获取服务管理器?如何在其他型号中执行此操作?
我发现了许多像这样的问题并尝试了很多,但仍然没有得到这个工作。也许Zend的版本差异? 我们使用Zend 2.3.7 。
答案 0 :(得分:2)
OpenUrl
服务取决于的配置。因此,配置是服务的依赖。没有它的配置就没有必要创建服务。
您已将bsz\openurl
服务注册为“可调用”类。这意味着当您请求服务时,服务管理器将实例化Bsz\Services\OpenUrl
类,而不传入任何构造函数参数。这不是您想要的,您需要配置为课程即将创建。
向服务工厂注册服务
为了实现这个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
依赖 OpenUrl
,那么您可以使用新的SomeServiceFactory
重复工厂流程,其中依赖关系为OpenUrl
。
答案 1 :(得分:0)
我现在找到第一个问题的答案: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
方法的其他模型中检索此服务?