Я новичок в SOAP WSDL FUNCTIONS. У меня есть клиент, которому был предоставлен wsdl-файл от компании, которая занимается тестированием автомобилей. Мой клиент является субподрядчиком для них. Они сказали нам загрузить информацию о автомобильной табличке, категории и т. Д. И после того, как будут отправлены детали. Будет получен ответ от сервера об успехе или неудаче. Пожалуйста, помогите в этом.
Просматривая другую информацию, я попытался сделать что-то вроде ниже, но не работает
<?php $data = array('1'=>'value','2'=>'value','3'=>'value','4'='value','5'=>'value'); $wsdl ='http://181.24.80.32/ws/services/servicename'; $client = new SoapClient($wsdl); $response = $client->servicenamerequest($data); echo $response->servicenamereturn; ?>
Прежде всего: Go get SoapUI, если вы имеете дело с неизвестным сервисом Soap. SoapUI прочитает файл WSDL и позволит вам посмотреть почти все, что связано с методами, параметрами и возвращаемыми значениями мыла (если вы решитесь сделать звонок на живую услугу – надеюсь, есть сервер песочницы, который ничего не делает).
Но SoapUI может помочь вам там, создав макет службы, которая получает ваш запрос и отвечает готовым запросом, который вы подготовили. Вот как я получил от связанного WSDL с примером рабочего кода, не касаясь реального сервиса.
Создайте новый проект в SoapUI и укажите местоположение WSDL. Вы можете назвать этот проект.
SoapUI затем считывает содержимое WSDL и создает проект, содержащий все описанные запросы. После этого вы увидите, какие методы предлагает сервис, и какие параметры должны войти в него, как дерево. Открывая это дерево, вы получите «Request 1» для каждого обнаруженного метода, который отображает некоторый XML в бесплатной версии (платная версия немного удобнее с заполняемой формой), как это (из метода vehiclePassedTest
):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tr="http://tr.gov.tp.stp.ws.PassedVehicleTestService"> <soapenv:Header> <tr:password>?</tr:password> <tr:username>?</tr:username> </soapenv:Header> <soapenv:Body> <tr:vehiclePassedTest> <chassisNo>?</chassisNo> <plateNo>?</plateNo> <plateCode>?</plateCode> <plateCategory>?</plateCategory> <plcEmiCode>?</plcEmiCode> <currentUserName>?</currentUserName> </tr:vehiclePassedTest> </soapenv:Body> </soapenv:Envelope>
Вопросительные знаки – это то место, где вы должны предоставить данные. Эта структура запроса должна быть создана вами с использованием SoapClient из PHP.
Давайте издеваться над этим. Mocking означает, что SoapUI запускает собственный Soap-сервер, который принимает запросы. Обычно он работает на 127.0.0.1:8080. Щелкните правой кнопкой мыши проект «PassedVehicleTestService» и выберите «Новый MockService». Примите имя, нажмите «ОК».
Щелкните правой кнопкой мыши метод, который вы хотите высмеять. Выберите «Добавить для mock service» и выберите созданную из предыдущего шага. Ответьте да, чтобы открыть редактор ответов. Там вы видите XML-структуру ответа с вопросительными знаками для данных, которые будут заполнены службой. Все ответы этой службы дают один ответ в виде строки, поэтому напишите что-нибудь приятное, которое будет возвращено. При необходимости вы можете добавить другие методы в эту службу позже.
Щелкните правой кнопкой мыши свой «MockService 1» и выберите «Start minimized». Это запустит Soap-сервер, он будет ждать входящего запроса.
Вам нужно знать две вещи. Сначала местоположение WSDL. Этот файл содержит адрес реального сервера, который будет использоваться для запросов, но PHP позволяет переопределить это. Таким образом, вторая информация, которая вам нужна, это адрес запущенного макетного сервиса.
SoapUI отображает адрес из WSDL в редакторе запросов. В вашем случае это http://181.24.80.32/ws/services/PassedVehicleTestService
– макет службы выполняется по http://127.0.0.1:8080/ws/services/PassedVehicleTestService
– IP и порт заменен, путь сохраняется ,
Это приводит к первым строкам кода PHP:
$options = array( 'location' => 'http://127.0.0.1:8080/ws/services/PassedVehicleTestService', ); $client = new SoapClient("http://www.quickregistration.ae/temp/PassedVehicleTestService.xml", $options);
После этого у вас есть сконфигурированный SoapClient, способный поговорить с вашим макетным сервисом. Если позже вы захотите использовать реальный сервис, выкиньте строку с «местоположением» из массива и сохраните остальные параметры конфигурации, если вы добавите некоторые из них.
С клиентом вы можете сделать $client->nameOfSoapMethod(paramStructure)
. Структура параметров обычно представляет собой смесь массивов или объектов и скалярных значений, таких как строки. Так вот что я пытаюсь в первую очередь:
$result = $client->vehiclePassedTest(array()); var_dump($result);
Затем я смотрю на SoapUI, чтобы узнать, что произойдет. Вывод из скрипта php:
Notice: Array to string conversion in [...]/soap.php on line 20 string(1) "?"
SoapUI говорит:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService"> <SOAP-ENV:Body> <ns1:vehiclePassedTest> <chassisNo>Array</chassisNo> <plateNo/> <plateCode/> <plateCategory/> <plcEmiCode/> <currentUserName/> </ns1:vehiclePassedTest> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Это был неправильный подход. Массив был преобразован в строку «Массив» и был помещен в качестве первого параметра. Остальное пусто. Приятно, потому что я знаю, что мыльные вызовы могут принимать больше одного параметра, и это одна из этих служб.
$result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName');
Это правильно отображается в SoapUI, но заголовки все еще отсутствуют.
SoapClient предлагает метод с именем __setSoapHeaders()
, и есть класс SoapHeader
.
В описании говорится, что setSoapHeaders () принимает один объект SoapHeader или массив объектов SoapHeader. Давайте его создадим, передадим и посмотрим, что получится:
$username = new SoapHeader(); $client->__setSoapHeaders($username); $result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName'); var_dump($result);
PHP говорит: Warning: SoapHeader::SoapHeader() expects at least 2 parameters, 0 given
$username = new SoapHeader('namespace', 'username', 'MyUserName');
Это работает. SoapUI говорит:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService" xmlns:ns2="namespace"> <SOAP-ENV:Header> <ns2:username>MyUserName</ns2:username> </SOAP-ENV:Header> <SOAP-ENV:Body> <ns1:vehiclePassedTest><chassisNo>chassisNo</chassisNo><plateNo>plateNo</plateNo><plateCode>plateCode</plateCode><plateCategory>plateCategory</plateCategory><plcEmiCode>plcEmiCode</plcEmiCode><currentUserName>currentUserName</currentUserName></ns1:vehiclePassedTest> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Обратите внимание на два атрибута xmlns в элементе SOAP-ENV: Envelope. Первоначальный запрос требует, чтобы имя пользователя находилось в пространстве имен «tr», но «tr» – это всего лишь ярлык для строки, которая определена как «xlmns: tr» – строка, стоящая за этим, является вашим пространством имен (хотя оно может уже работать с реальный сервис).
$username = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'username', 'myUser'); $password = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'password', 'yetAnotherPassword'); $client->__setSoapHeaders(array($username, $password));
Это правильно определяет заголовки, как вы можете видеть:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService"> <SOAP-ENV:Header> <ns1:username>myUser</ns1:username> <ns1:password>yetAnotherPassword</ns1:password> </SOAP-ENV:Header> <SOAP-ENV:Body> <ns1:vehiclePassedTest><chassisNo>chassisNo</chassisNo><plateNo>plateNo</plateNo><plateCode>plateCode</plateCode><plateCategory>plateCategory</plateCategory><plcEmiCode>plcEmiCode</plcEmiCode><currentUserName>currentUserName</currentUserName></ns1:vehiclePassedTest> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
В элементе конверта нет двух пространств имен, и каждый элемент имеет пространство имен «ns1». Это должно сработать.
Ваш окончательный код:
$options = array( 'location' => 'http://127.0.0.1:8080/ws/services/PassedVehicleTestService', ); $client = new SoapClient("http://www.quickregistration.ae/temp/PassedVehicleTestService.xml", $options); $username = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'username', 'myUser'); $password = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'password', 'yetAnotherPassword'); $client->__setSoapHeaders(array($username, $password)); $result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName'); var_dump($result);
попробуйте что-то вроде этого. Работает на меня.
try { $client = new SoapClient("http://wsdl", array('trace' => 1)); $data = $client->someFunction(array('parma1' => 'value1', 'param2' => 'value2')); print_r($data); } catch (SoapFault $fault) { trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR); exit(); }
И проверьте, что вы установили пакет php-soap на свой сервер.
ПОЗДРАВЛЕНИЯ.