2013-06-25 65 views
6

我準備SOAP服務器和使用後續的碼生成我的WSDL:Zend框架2 SOAP自動發現和複雜類型

//(... Controller action code ...) 
if (key_exists('wsdl', $params)) { 
    $autodiscover = new AutoDiscover(); 
    $autodiscover->setClass('WebServiceClass') 
       ->setUri('http://server/webserver/uri'); 
    $autodiscover->handle(); 
} else { 
    $server = new Server(null); 
    $server->setUri($ws_url); 
    $server->setObject($this->getServiceLocator()->get('MyController\Service\WebServiceClass')); 
    $server->handle(); 
} 

//(... Controller action code ...) 

但在我的WebService方法的一個予有陣列類型的參數,其中每個元素的類型是「MyOtherClass」,就像如下:

/** 
    * Add list of MyOtherClass items 
    * 
    * @param MyOtherClass[] $items 
    * 
    * @return bool 
    */ 
    function add($items) { 
     // Function code here 
    } 

當我嘗試生成WSDL,我得到了如下錯誤:

PHP Warning: DOMDocument::loadXML(): Empty string supplied as input in /<zend framweork path>/Server/vendor/zendframework/zendframework/library/Zend/Soap/Server.php on line 734 

或者此異常:

Cannot add a complex type MyOtherClass[] that is not an object or where class could not be found in "DefaultComplexType" strategy. 

當我加入到我的代碼是這樣的:

​​

我得到了如下錯誤信息:

Fatal error: Call to a member function getTypes() on a non-object in /<project dir>/vendor/zendframework/zendframework/library/Zend/Soap/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php on line 54 

在恢復,問題是:我如何知道用作參數的新自定義類型的WSDL?

感謝

+0

'MyOtherClass []'在php上下文中看起來不對。 我想嘗試創建一個包含元素的MyOtherClassCollection對象。 – DanielKhan

+0

'MyOtherClass []'定義一個MyOtherClass對象的數組。對於Zend \ Soap \ AutoDiscover模式'ArrayOfTypeSequence'和'ArrayOfTypeComplex',這在PHP中是完全正常的。 –

回答

3

我沒有類似的東西,這是一個示例代碼:

/* code.... */ 
if (array_key_exists('wsdl', $this->request->getQuery()) || array_key_exists('WSDL', $this->request->getQuery())) { 

        $auto = new \Zend\Soap\AutoDiscover(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence()); 

        $auto->setClass($controllerClassName); 
        $auto->setUri(sprintf('%s://%s%s', \Application\Bootstrap::getServiceManager()->get('config')[APPLICATION_ENV]['webServer']['protocol'], 
                $this->request->getUri()->getHost() , $this->request->getUri()->getPath())); 
        $auto->setServiceName(ucfirst($this->request->getModuleName()) . ucfirst($this->request->getControllerName())); 

        header('Content-type: application/xml'); 

        echo $auto->toXML(); 



       } elseif (count($this->request->getQuery()) == 0) { 

        $this->preDispatch(); 

        $wsdl = sprintf('%s://%s%s?wsdl', \Application\Bootstrap::getServiceManager()->get('config')[APPLICATION_ENV]['webServer']['protocol'], 
                $this->request->getUri()->getHost() , $this->request->getUri()->getPath()); 

        $soapServer = new \Zend\Soap\Server($wsdl); 
        $soapServer->setClass($controllerClassName); 
        $soapServer->handle(); 
       } 

/* code */ 

這是自動發現將生成WSDL的一個類的函數簽名的基礎上,片段註釋:

/** 
* Allows to search for a patient based on the patient id 
* 
* @param int $id 
* @return \ViewModels\PatientViewModel 
* @throws \Application\Exception 
*/ 
protected function searchPatientById($id) { 
/* .... code */ 

這是類\的ViewModels \ PatientViewModel和\視圖模型\ DiagnosisViewModel 注意在這裏,我如何使用的註釋來聲明的字段conatins的complexType的陣列,並且被再怎麼譯爲ArrayOfDiagnosisViewModel上的wsdl

namespace ViewModels; 

    class PatientViewModel { 

     /** 
     * @var int 
     * */ 
     public $id; 

     /** 
     * @var string 
     * */ 
     public $firstname; 

     /** 
     * @var string 
     * */ 
     public $lastname; 

     /** 
     *** @var \ViewModels\DiagnosisViewModel[]** 
     * */ 
     public $diagnosis; 

    } 

class DiagnosisViewModel { 

    /** 
    * @var int 
    */ 
    public $id; 

    /** 
    * @var string 
    */ 
    public $name; 

} 

而這是WSDL產生

<?xml version="1.0" encoding="UTF-8"?> 
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://soa.local/soap/Sample/Main" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" name="SampleMain" targetNamespace="http://soa.local/soap/Sample/Main"> 
    <types> 
     <xsd:schema targetNamespace="http://soa.local/soap/Sample/Main"> 
      <xsd:complexType name="DiagnosisViewModel"> 
       <xsd:all> 
        <xsd:element name="id" type="xsd:int" nillable="true"/> 
        <xsd:element name="name" type="xsd:string" nillable="true"/> 
       </xsd:all> 
      </xsd:complexType> 
      **<xsd:complexType name="ArrayOfDiagnosisViewModel"> 
       <xsd:sequence> 
        <xsd:element name="item" type="tns:DiagnosisViewModel" minOccurs="0" maxOccurs="unbounded"/> 
       </xsd:sequence> 
      </xsd:complexType>** 
      <xsd:complexType name="PatientViewModel"> 
       <xsd:all> 
        <xsd:element name="id" type="xsd:int" nillable="true"/> 
        <xsd:element name="firstname" type="xsd:string" nillable="true"/> 
        <xsd:element name="lastname" type="xsd:string" nillable="true"/> 
        <xsd:element name="diagnosis" type="tns:ArrayOfDiagnosisViewModel" nillable="true"/> 
       </xsd:all> 
      </xsd:complexType> 
     </xsd:schema> 
    </types> 
    <portType name="SampleMainPort"> 
     <operation name="searchPatientById"> 
      <documentation>Allows to search for a patient based on the patient id</documentation> 
      <input message="tns:searchPatientByIdIn"/> 
      <output message="tns:searchPatientByIdOut"/> 
     </operation> 
    </portType> 
    <binding name="SampleMainBinding" type="tns:SampleMainPort"> 
     <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 
     <operation name="searchPatientById"> 
      <soap:operation soapAction="http://soa.local/soap/Sample/Main#searchPatientById"/> 
      <input> 
       <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://soa.local/soap/Sample/Main"/> 
      </input> 
      <output> 
       <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://soa.local/soap/Sample/Main"/> 
      </output> 
     </operation> 
    </binding> 
    <service name="SampleMainService"> 
     <port name="SampleMainPort" binding="tns:SampleMainBinding"> 
      <soap:address location="http://soa.local/soap/Sample/Main"/> 
     </port> 
    </service> 
    <message name="searchPatientByIdIn"> 
     <part name="id" type="xsd:int"/> 
    </message> 
    <message name="searchPatientByIdOut"> 
     <part name="return" type="tns:PatientViewModel"/> 
    </message> 
</definitions> 

注意只要更改您可以實現的策略和正確的DOCBLOCKS註釋。

希望這些SNIPPETS可以幫助您找到解決方案。

+0

嗨!謝謝,我會檢查它並讓你知道。 +1的想法。 – leticia

+0

我得到的全部是: 無法添加不是對象的複雜類型\ ViewModels \ DiagnosisViewModel **,也無法在「DefaultComplexType」策略中找不到類。 我錯過了什麼? thx提前! – wolxXx