2013-06-25 6 views
6

Ich bereite den SOAP-Server und meine WSDL Erzeugung des Folge Code verwendet:Zend Framework 2 SOAP Autoermittlung und komplexe Typen

//(... 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 ...) 

Aber in einem meiner WebService-Methode habe ich einen Parameter vom Typ Array, in dem jedes Element ist vom Typ "MyOtherClass", wie folgt:

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

Wenn ich versuche, den WSDL ich die folgenden Fehler erhalten zu generieren:

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 

Oder diese Ausnahme:

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

Wenn ich meinen Code so etwas wie dies hinzugefügt:

//(...) 
if (key_exists('wsdl', $params)) { 

    $autodiscover = new AutoDiscover(); 
    $autodiscover->setClass('WebServiceClass'); 
    $autodiscover->setUri($ws_url); 

    $complex_type_strategy = new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex(); 
    $complex_type_strategy->addComplexType('MyOtherClass'); 
    $autodiscover->setComplexTypeStrategy($complex_type_strategy); 
    $autodiscover->handle(); 
} else { 
//(...) 

ich die folgende Fehlermeldung erhalten:

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 

In Lebenslauf, die Frage ist, : Wie kann ich auf die WSDL des neuen benutzerdefinierten Typs aufmerksam machen, der als Parameter verwendet wird?

Dank

+0

'MyOtherClass []' sieht mir im PHP-Kontext falsch. Ich möchte versuchen, ein MyOtherClassCollection-Objekt zu erstellen, das die Elemente enthält. – DanielKhan

+0

'MyOtherClass []' definiert ein Array von MyOtherClass-Objekten. Dies ist in PHP für die Zend \ Soap \ AutoDiscover-Modi 'ArrayOfTypeSequence' und' ArrayOfTypeComplex' völlig in Ordnung. –

Antwort

3

habe ich etwas Ähnliches, und dies ist ein Beispielcode:

/* 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 */ 

Dies ist ein Fragment der Funktionssignatur von einer der Klassen, die die Autoermittlungs die WSDL auf der Basis generieren Anmerkungen: Dieses

/** 
* 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 */ 

ist die Klasse \ Viewmodels \ PatientViewModel und \ Viewmodel \ DiagnosisViewModel Hinweis hier, wie ich die Anmerkungen verwendet, um zu erklären, dass ein Feld ein Array eines complex conatins, und dann, wie das als ArrayOfDiagnosisViewModel auf der WSDL-Datei übersetzt

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; 

} 

Und das ist die 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> 
erzeugt

BEACHTEN SIE, DASS SIE NUR DURCH ÄNDERUNG DER STRATEGIE UND DER RICHTIGEN DOCBLOCKS ANNOTATIONEN DAS ERREICHEN KÖNNEN.

HOFFNUNG DIESE SNIPPETS können Ihnen helfen, eine Lösung zu finden.

+0

Hallo! Danke, ich werde es überprüfen und Sie wissen lassen. +1 für die Ideen. – leticia

+0

alles, was ich bekomme ist: Kann nicht einen komplexen Typ \ ViewModels \ DiagnosisViewModel ** hinzufügen, die kein Objekt oder wo Klasse nicht in "DefaultComplexType" -Strategie gefunden werden kann. was fehlt mir? Danke im Voraus! – wolxXx