Я не уверен, что это ошибка php (плохая реализация) или моя ошибка (плохое понимание протокола SOAP / SoapServer, поскольку это первый раз, когда я использую SoapServer)
Я заметил, что если есть две или более операции с одной и той же wsdl:part
(даже если wsdl:message
, operation и 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 (с добавлением записи – адаптировано из этого сообщения ), но проблема возникает, когда я использую простой 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
– это в основном один и тот же файл с двумя исключениями:
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
) Это полный wsdl service.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>
пространство<?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 от «document» до «rpc».
Сначала я думал, что это проблема с кешем, так как ваш вышеперечисленный код сервера не содержит ini_set (), чтобы отключить кеш. Но это не проблема с кешем.
Проследить трафик http. Клиент, кажется, работает порче, это проблема SoapServer. (Как вы упомянули) .. Дальнейшее расследование …
Отчет об ошибке уже подан – хотя в настоящее время неясно, является ли это ошибкой.
Обходные пути упоминаются также в отчете об ошибке. Вы можете изменить стиль привязки на rpc, если это нормально для вас:
+ Изменить
<soap:binding style="document"
в
<soap:binding style="rpc"
Это обходное решение работает для меня. Вы найдете очень интересную статью о том, как работают стили привязки. Это может помочь вам решить, подходит ли стиль привязки rpc для вас или нет.