用两个词来说:我需要从外部类访问服务管理器(定位器)。
详细说明:
我的ZF2项目中有下一个结构:
Api.php是我在SOAP服务器中使用的类,它在Controller中创建:
class IncomingInterfaceController extends AbstractActionController
{
...
public function indexAction()
{
if (isset($_GET['wsdl']))
$this->handleWSDL();
else
$this->handleSOAP();
return $this->getResponse();
}
private function handleWSDL()
{
$autodiscover = new AutoDiscover();
$autodiscover->setClass('\Application\Api\Api')->setUri($this->getURI());
$autodiscover->handle();
}
在这个Api.php课程中,我需要访问服务。
我在Api.php课程中需要这样的东西:
public function OnNewDeal($uid)
{
$error_log=$this->getServiceLocator()->get('error_log'); // this doesn't work!
$error_log->write_error('error_text');
}
答案 0 :(得分:2)
在Module.php中
public function getServiceConfig() {
return array(
'invokables' => array(
'Application\Api\Api' => 'Application\Api\Api'
)
);
}
在Api.php中
class Api implements ServiceLocatorAwareInterface{
protected $services;
public function OnNewDeal($uid){
$this->getServiceLocator()->get('error_log')->write_error('SOAP ERROR');
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator){
$this->services = $serviceLocator;
}
public function getServiceLocator(){
return $this->services;
}
}
IncomingInterfaceController.php
class IncomingInterfaceController extends AbstractActionController{
...
protected $api;
public function indexAction()
{
if (isset($_GET['wsdl']))
$this->handleWSDL();
else
$this->handleSOAP();
return $this->getResponse();
}
private function handleWSDL()
{
$autodiscover = new AutoDiscover();
$autodiscover->setClass('\Application\Api\Api')->setUri($this->getURI());
$autodiscover->handle();
}
public getApi(){
if(!$api){
$this->api = $this->getServiceLocator()->get('Application\Api\Api');
}
return $this->api;
}
答案 1 :(得分:1)
在你执行$ this-> handleSOAP()的控制器中;将 setObject 与已创建的实例一起使用 setClass 。
你应该转入Api __construct $ this-> getServiceLocator()并在那里处理它。
class IncomingInterfaceController extends AbstractActionController
{
private function handleSOAP()
{
$soap = new Server(null, array('wsdl'=>$this->getWSDLURI()));
$soapClass = new \Application\Api\Api($this->getServiceLocator());
$soap->setObject($soapClass);
$soap->handle();
}
在Api类中,处理serviceManager实例并按照您的意愿使用:
class Api
{
protected $serviceManager;
public function __construct($serviceManager)
{
$this->serviceManager = $serviceManager;
}
public function OnNewDeal($uid)
{
$this->serviceManager->get('error_log')->write_error('SOAP ERROR');
}
....
}
答案 2 :(得分:1)
也许您的API可以实现ServiceLocatorAwareInterface,如:
class Api implements ServiceLocatorAwareInterface
并添加
class Api implements ServiceLocatorAwareInterface
{
protected $serviceManager;
}
然后服务经理可用
的修订版强> 的
module.config.php示例
<?php
return array(
'service_manager' => array(
'factories' => array(
'Api' => 'Namespace\Api'
),
'shared' => array(
'Api' => false
)
),
)
?>
答案 3 :(得分:1)
将Service Manager实例注入用户定义的“服务定位器感知类”应该对框架本身(通过初始化程序,可调用程序或用户定义的工厂)的责任不是特定控制器的handleSOAP()方法。
是的,@ SirJ的解决方案也会起作用,但这不是一个好习惯。 ZF2提供了准备使用的Traits和接口,完全符合这样的要求。只需使用它们!
您自己的API类应如下所示:
<?php
namespace Application\Api;
use Zend\ServiceManager\ServiceLocatorInterface;
class Api implements ServiceLocatorInterface
{
// Here is the trait. (php >= 5.4)
use \Zend\ServiceManager\ServiceLocatorAwareTrait;
public function OnNewDeal($uid)
{
$this->getServiceLocator()->get('error_log')->write_error('SOAP ERROR');
}
}
您应该将此密钥添加到您的module.config.php
<?php
return array(
'service_manager' => array(
'invokables' => array(
'api-service' => 'Application\Api\Api',
)
);
多数民众赞成!现在你可以:
<?php
...
$soap = new Server(null, array('wsdl'=>$this->getWSDLURI()));
$soapClass = $this->getServiceLocator()->get('api-service');
$soap->setObject($soapClass);
...