У меня проблема с подключением SOAP-запроса к веб-сервису.
Во-первых, это мой код:
$soapClient = new NewSoapClient(null, [
'location' =>
"https://www.phobs.net/test/webservice/pc/service.php",
'uri' => "http://www.opentravel.org/OTA/2003/05",
'trace' => 1,
"soap_version" => SOAP_1_1,
]);
$ns_wsse = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
$password_type = 'ns2:http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
// Creating WSS identification header using SimpleXML
$root = new \SimpleXMLElement('<root/>');
$security = $root->addChild('ns2:Security', null, $ns_wsse);
$usernameToken = $security->addChild('ns2:UsernameToken', null, $ns_wsse);
$usernameToken->addChild('ns2:Username', 'username', $ns_wsse);
$usernameToken->addChild('ns2:Password', 'pass', $ns_wsse)->addAttribute('xsi:xsi:type', $password_type);
$root->registerXPathNamespace('ns2', $ns_wsse);
$full = $root->xpath('/root/ns2:Security');
$auth = $full[0]->asXML();
$auth = str_replace(' xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"','', $auth);
$soapClient->__setSoapHeaders(new \SoapHeader($ns_wsse, 'Security', new \SoapVar($auth, XSD_ANYXML), true));
try {
$response = $soapClient->__soapCall("OTA_RoomRateListRQ",[
new \SoapVar('<ns1:HotelInfo HotelCode="' . 'ATL476' . '" DestinationSystemCode="' . 'ATLANTIS' . '" />', XSD_ANYXML)
]);
} catch (\SoapFault $exception)
{
var_dump($exception);
//die();
}
$response = json_decode(json_encode((array)simplexml_load_string($soapClient->__getLastResponse())),1);
И у меня есть оболочка для собственного класса PHP клиента Soap:
class NewSoapClient extends \SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way = 0)
{
$string = '<?xml version="1.0" encoding="UTF-8"?>';
$request = str_replace($string , '', $request);
$request = str_replace('xmlns:xsd="http://www.w3.org/2001/XMLSchema"', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', $request);
$request = str_replace('xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"', '', $request);
$request = str_replace('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">', $request);
$request = trim($request);
return parent::__doRequest($request, $location, $action, $version, $one_way); // TODO: Change the autogenerated stub
}
}
Таким образом, в основном он подключается к веб-службе SOAP (без WSDL) и получает некоторые данные.Большая часть этого кода предназначена только для манипулирования строками (или XML), поэтому запрос может выглядеть точно так же, как в документации веб-службы SOAP.Окончательный запрос (после всех модификаций) выглядит следующим образом:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.opentravel.org/OTA/2003/05"
xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<ns2:Security>
<ns2:UsernameToken>
<ns2:Username>username</ns2:Username>
<ns2:Password xsi:type="ns2:http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass</ns2:Password>
</ns2:UsernameToken>
</ns2:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:OTA_RoomRateListRQ>
<ns1:HotelInfo HotelCode="ATL476" DestinationSystemCode="ATLANTIS" />
</ns1:OTA_RoomRateListRQ>
</SOAP-ENV:Body>
Так что в основном мой запрос такой же, как запрос в документации.Когда я запускаю этот код, я получаю исключение SoapFault с сообщением «Неверная версия» и кодом ошибки «VersionMismatch» и с кодами ошибок »http://schemas.xmlsoap.org/soap/envelope/".
Важная вещь, на которую следует обратить внимание, если я перевожу вызов SOAP в блоки try / catch иесли я не использую логику, которая реагирует на исключение (оставляя блок catch пустым), ответ будет возвращен с кодом состояния 200, и он будет нормально проанализирован, и мой скрипт завершит выполнение без ошибок.
Исключение определенно генерируется, но если я не реагирую на него, жизненный цикл запроса завершается успешно. В чем причина этой ошибки? Как ее устранить? Стоит ли просто оставлять блок catch открытым без какой-либо логики? Есть ли лучшее решение??
Немного больше информации о системе. Версия SOAP такая же, как в документации (1.1). Моя версия PHP - 7.2, у меня нет доступа к SOAP-серверу, поэтому работающая там версия неизвестна ...
Спасибо