ZF2:从外部类访问服务管理器(定位器)

时间:2013-11-01 13:21:48

标签: php soap zend-framework2 service-provider

用两个词来说:我需要从外部类访问服务管理器(定位器)。

详细说明:

我的ZF2项目中有下一个结构:

project structure

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');
}

4 个答案:

答案 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);
...