ZF2 and the implementation of a SOAP server returning a complex type

I am trying to implement a SOAP server using Zend Framework 2 in PHP5.5. I got to this:

library.php

<?php namespace Library; class IncrementedInt { /** * @var integer **/ public $original; /** * @var integer **/ public $incremented; public function __construct($num) { $this->original = $num; $this->incremented = ++$num; } } 

webservice.php

 <?php require_once 'library.php'; require_once 'Zend/Loader/StandardAutoloader.php'; $loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true)); $loader->register(); class Math { /** * This method takes ... * * @param integer $inputParam * @return \Library\IncrementedInt */ public function increment($inputParam) { return new \Library\IncrementedInt($inputParam); } } if (isset($_GET['wsdl'])) { $autodiscover = new \Zend\Soap\AutoDiscover(); $autodiscover->setClass('Math') ->setBindingStyle(array('style' => 'document')) ->setUri('http://localhost' . $_SERVER['SCRIPT_NAME']); header('Content-type: application/xml'); echo $autodiscover->toXml(); } else { // pointing to the current file here $soap = new \Zend\Soap\Server('http://localhost' . $_SERVER['SCRIPT_NAME'] . '?wsdl'); $soap->setClass('Math'); $soap->handle(); } 

Loading the URL http://localhost/webservice.php?wsdl in the browser will display:

 <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://localhost/webservice.php" 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="Math" targetNamespace="http://localhost/webservice.php"> <script/> <types> <xsd:schema targetNamespace="http://localhost/webservice.php"> <xsd:element name="increment"> <xsd:complexType> <xsd:sequence> <xsd:element name="inputParam" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:complexType name="IncrementedInt"> <xsd:all> <xsd:element name="original" type="xsd:int" nillable="true"/> <xsd:element name="incremented" type="xsd:int" nillable="true"/> </xsd:all> </xsd:complexType> <xsd:element name="incrementResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="incrementResult" type="tns:IncrementedInt"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </types> <portType name="MathPort"> <operation name="increment"> <documentation>This method takes ...</documentation> <input message="tns:incrementIn"/> <output message="tns:incrementOut"/> </operation> </portType> <binding name="MathBinding" type="tns:MathPort"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="increment"> <soap:operation soapAction="http://localhost/webservice.php#increment"/> <input> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="MathService"> <port name="MathPort" binding="tns:MathBinding"> <soap:address location="http://localhost/webservice.php"/> </port> </service> <message name="incrementIn"> <part name="parameters" element="tns:increment"/> </message> <message name="incrementOut"> <part name="parameters" element="tns:incrementResponse"/> </message> </definitions> 

As you can see, the IncrementedInt class and its original and incremented properties are defined. However, when I call the service sending this XML (using soapUI ):

 <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://localhost/webservice.php"> <soapenv:Header/> <soapenv:Body> <web:increment> <inputParam xsi:type="xsd:int">2</inputParam> </web:increment> </soapenv:Body> </soapenv:Envelope> 

The server will respond as follows:

 <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/webservice.php" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:incrementResponse> <return xsi:type="ns1:IncrementedInt"/> </ns1:incrementResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

As you can see, the return value is not expanded, and it is exactly the same as the type. Has anyone successfully returned a complex type on a ZF2 SOAP server? How? I searched the Internet for an example, but I could not find it!

0
source share
1 answer

It turned out that all I was missing was that the Zend Framework caches WSDL by default. Therefore, I only needed:

 <?php require_once 'library.php'; require_once 'Zend/Loader/StandardAutoloader.php'; $loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true)); $loader->register(); class Math { /** * This method takes ... * * @param integer $inputParam * @return \Library\IncrementedInt */ public function increment($inputParam) { return new \Library\IncrementedInt($inputParam); } } if (isset($_GET['wsdl'])) { $autodiscover = new \Zend\Soap\AutoDiscover(); $autodiscover->setClass('Math') ->setUri('http://localhost' . $_SERVER['SCRIPT_NAME']); header('Content-type: application/xml'); echo $autodiscover->toXml(); } else { // pointing to the current file here $soap = new \Zend\Soap\Server('http://localhost' . $_SERVER['SCRIPT_NAME'] . '?wsdl', array('cache_wsdl' => WSDL_CACHE_NONE)); $soap->setClass('Math'); $soap->handle(); } 

Changes:

  • When you create a Server instance, it is installed as an option to disable WSDL caching.
  • The method call ->setBindingStyle(array('style' => 'document')) omitted on AutoDiscovery because it causes problems and prevents a successful SOAP call.
+1
source

Source: https://habr.com/ru/post/952426/


All Articles