0

我正在尝试使用 PHP5.5 中的 Zend Framework 2 实现一个 SOAP 服务器。我已经做到了:

库.php

<?php
namespace Library;

class IncrementedInt
{
    /**
     * @var integer
     **/
    public $original;

    /**
     * @var integer
     **/
    public $incremented;

    public function __construct($num)
    {
        $this->original = $num;
        $this->incremented = ++$num;
    }
}

网络服务.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();
}

在浏览器中加载 URLhttp://localhost/webservice.php?wsdl将输出:

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

如您所见,该类IncrementedInt及其属性已被定义。然而,当我通过发送此 XML 调用服务时(使用):originalincrementedsoapUI

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

服务器将响应如下:

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

如您所见,返回值没有扩展,就像类型被命名一样。有没有人在 ZF2 SOAP 服务器中成功返回了一个复杂类型?如何?我在互联网上搜索了一个示例,但找不到任何示例!

4

1 回答 1

1

事实证明,我所缺少的只是 Zend Framework 默认缓存 WSDL 的事实。所以我需要做的就是:

<?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();
}

这些变化是:

  1. 实例化 aServer时,它被设置为禁用 WSDL 缓存的选项。
  2. ->setBindingStyle(array('style' => 'document'))方法调用AutoDiscovery被省略,因为它会导致麻烦并阻止成功的 SOAP 调用。
于 2013-09-18T12:09:53.670 回答