【问题标题】:SoapServer maps functions incorectly when the wsdl messages have the same part name当 wsdl 消息具有相同的部分名称时,SoapServer 不正确地映射函数
【发布时间】:2012-12-19 17:10:07
【问题描述】:

我不确定这是 php 错误(错误的实现)还是我的错误(对 SOAP 协议/SoapServer 的理解不佳,因为这是我第一次使用 SoapServer)

我注意到如果有两个或多个具有相同wsdl:part 的操作(即使wsdl:message,操作和soapAction 不同),SoapServer 将始终调用第一个函数。在此示例中,我有两个函数 multiply2multiply4 都将 num (int) 作为输入参数。今天早些时候,如果我更改部件名称(service1.wsdl),则功能映射正确。

虽然,我不介意使用不同的名称,但在我看来它就像一个错误。我错过了什么还是应该打开一个错误?

这是我创建的简单示例:

非常简单的php类

<?php
class Multi
{
    function multiply2($num) { return ($num * 2 ); }
    function multiply4($num){ return ($num * 4 );  }
}
?>

并且稍微改变了 SoapServer(添加了日志记录 - adapted from this post)但是当我使用普通的 SoapServer 时也会出现问题:

$server = new overloadedSoapServer("service.wsdl", array('soap_version' => SOAP_1_2,'encoding' => SOAP_ENCODED));
$server->setClass("multi");

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $server->handle();
} 

这是客户端代码:

ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient('service.wsdl');
$client1 = new SoapClient('service1.wsdl');
echo "<pre>\nFrom service.wsdl:";
echo  "\n".$client->multiply2(10);
echo  "\n".$client->multiply4(10);
echo "</pre>";
echo "<pre>\nFrom service1.wsdl:";
echo  "\n".$client1->multiply2(10);
echo  "\n".$client1->multiply4(10);
echo "</pre>";

service.wsdlservice1.wsdl基本上是同一个文件,有两个例外:

  1. 它们的端点不同(service.wsdl 指向http://tests.simsimy.info/web/service.phpservice1.php 指向http://tests.simsimy.info/web/service1.php 每个端点使用适当的wsdl 来加载SoapServer
  2. service.wsdlmultiply2Requestmultiply4Request 中具有作为部件名称-num,而在service1.wsdl 中名称不同(num2num4

这是 service.wsdl 的完整 wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://tests.simsimy.info/web/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="service"
    targetNamespace="http://tests.simsimy.info/web/">
    <wsdl:message name="multiply2Request">
        <wsdl:part name="num" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply2Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

    <wsdl:message name="multiply4Request">
        <wsdl:part name="num" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply4Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:portType name="dd">
        <wsdl:operation name="multiply2">
            <wsdl:input message="tns:multiply2Request"></wsdl:input>
            <wsdl:output message="tns:multiply2Response"></wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="multiply4">
            <wsdl:input message="tns:multiply4Request"></wsdl:input>
            <wsdl:output message="tns:multiply4Response"></wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="serviceSOAP" type="tns:dd">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="multiply2">
            <soap:operation soapAction="http://tests.simsimy.info/web/multiply2" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="multiply4">
            <soap:operation soapAction="http://tests.simsimy.info/web/multiply4" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="multiply_service">
        <wsdl:port binding="tns:serviceSOAP" name="serviceSOAP">
            <soap:address location="http://tests.simsimy.info/web/service.php" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

service1.wsdl中的改动部分:

<wsdl:message name="multiply2Request">
        <wsdl:part name="num2" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply2Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

    <wsdl:message name="multiply4Request">
        <wsdl:part name="num4" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply4Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

当我运行客户端代码时,我得到以下输出:

From service.wsdl:
20
20

From service1.wsdl:
20
40

【问题讨论】:

    标签: php soapserver


    【解决方案1】:

    您可以将 wsdl 中的绑定样式从“document”更改为“rpc”。

    首先我认为这是一个缓存问题,因为您在上面发布的服务器代码不包含用于禁用缓存的 ini_set()。但这不是缓存问题。

    已跟踪 http 流量。客户端似乎正常工作,这是一个 SoapServer 问题。 (就像你提到的).. 进一步调查......

    错误报告已经filed - 尽管目前还不清楚它是否是错误。

    错误报告中也提到了解决方法。如果这对您来说可以,您可以将绑定样式更改为 rpc:

    改变

    <soap:binding style="document"
    

    <soap:binding style="rpc"
    

    此解决方法对我有用。你会发现一篇关于绑定样式如何工作的非常有趣的文章here。这可以帮助您确定 rpc 绑定样式是否适合您。

    【讨论】:

    • 不是缓存使用,位服务器和客户端将soap.wsdl_cache_enabled设置为0,临时文件夹中没有缓存。
    • 好的,在我的测试中,这会导致像你这样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多