我不确定这是 php bug(糟糕的实现)还是我的 bug(对 SOAP 协议(protocol)/SoapServer 的理解不好,因为这是我第一次使用 SoapServer)
我注意到,如果有两个或多个操作具有相同的 wsdl:part
(即使 wsdl:message
、操作和soapAction 不同), SoapServer
将始终调用第一个函数。在此示例中,我有两个函数 multiply2
和 multiply4
,它们都以 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.wsdl
和 service1.wsdl
基本上是相同的文件,但有两个异常(exception):
- 它们的端点不同(
service.wsdl
指向http://tests.simsimy.info/web/service.php
和service1.php
到http://tests.simsimy.info/web/service1.php
每个端点使用适当的 wsdl 来加载SoapServer
) - 在
service.wsdl
multiply2Request
和multiply4Request
中具有作为部分名称 -num
,而在>service1.wsdl
名称不同(num2
和num4
)
这是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
最佳答案
您可以将 wsdl 中的绑定(bind)样式从“document”更改为“rpc”。
首先,我认为这是一个缓存问题,因为上面发布的服务器代码不包含 ini_set() 来禁用缓存。但这不是缓存问题。
已跟踪 http 流量。客户端似乎工作正常,这是 SoapServer 的问题。 (就像你提到的)..进一步调查...
错误报告已被 filed - 虽然目前还不清楚这是否是一个错误。
错误报告中也提到了解决方法。如果您可以的话,您可以将绑定(bind)样式更改为 rpc:
改变
<soap:binding style="document"
至
<soap:binding style="rpc"
这个解决方法对我有用。您会发现一篇非常有趣的文章,介绍绑定(bind)样式如何工作 here 。这可以帮助您决定 rpc 绑定(bind)样式是否适合您。
关于php - 当 wsdl 消息具有相同的部分名称时,SoapServer 会错误地映射函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13957539/