Как сделать SOAP-вызов PHP с использованием класса SoapClient

Я привык писать PHP-код, но не часто использую объектно-ориентированное кодирование. Теперь мне нужно взаимодействовать с SOAP (как клиент), и я не могу правильно получить синтаксис. У меня есть файл WSDL, который позволяет мне правильно настроить новое соединение с использованием класса SoapClient. Тем не менее, я не могу сделать правильный звонок и вернуть данные. Мне нужно отправить следующие (упрощенные) данные:

  • Контактный идентификатор
  • Контактное лицо
  • Общее описание
  • Количество

В документе WSDL есть две функции, но мне нужен только один («FirstFunction» ниже). Вот сценарий, который я запускаю, чтобы получить информацию о доступных функциях и типах:

$client = new SoapClient("http://example.com/webservices?wsdl"); var_dump($client->__getFunctions()); var_dump($client->__getTypes()); 

И вот результат, который он генерирует:

 array( [0] => "FirstFunction Function1(FirstFunction $parameters)", [1] => "SecondFunction Function2(SecondFunction $parameters)", ); array( [0] => struct Contact { id id; name name; } [1] => string "string description" [2] => string "int amount" } 

Скажем, я хочу позвонить в FirstFunction с данными:

  • ID контакта: 100
  • Контактное лицо: John
  • Общее описание: Баррель нефти
  • Количество: 500

Какой будет правильный синтаксис? Я пробовал всевозможные варианты, но кажется, что мыльная структура довольно гибкая, поэтому есть очень много способов сделать это. Не удалось понять это из руководства …


ОБНОВЛЕНИЕ 1: опробованный образец из MMK:

 $client = new SoapClient("http://example.com/webservices?wsdl"); $params = array( "id" => 100, "name" => "John", "description" => "Barrel of Oil", "amount" => 500, ); $response = $client->__soapCall("Function1", array($params)); 

Но я получаю этот ответ: у Object has no 'Contact' property . Как вы можете видеть на выходе getTypes() , существует struct называемая Contact , поэтому, я думаю, мне почему-то нужно уточнить, что мои параметры включают данные Contact, но вопрос в следующем: как?

ОБНОВЛЕНИЕ 2: Я также пробовал эти структуры, такую ​​же ошибку.

 $params = array( array( "id" => 100, "name" => "John", ), "Barrel of Oil", 500, ); 

Так же как:

 $params = array( "Contact" => array( "id" => 100, "name" => "John", ), "description" => "Barrel of Oil", "amount" => 500, ); 

Ошибка в обоих случаях: объект не имеет свойства «Контакт»

Это то, что вам нужно сделать.

Просто, чтобы знать, я пытался воссоздать вашу ситуацию …


  • В этом примере я создал web-сервис .NET с WebMethod под названием Function1 и это параметры:

Function1 (контактный контакт, описание строки, int amount)

  • В котором Contact является только class bean, который имеет getters и seters для id и name как в вашем случае.

  • Вы можете загрузить этот образец webservice .NET по адресу:

https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.zip


Код.

Это то, что вам нужно сделать на стороне PHP :

(Протестировано и работает)

 <?php /* Create a class for your webservice structure, in this case: Contact */ class Contact { function Contact($id, $name) { $this->id = $id; $this->name = $name; } } /* Initialize webservice with your WSDL */ $client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl"); /* Fill your Contact Object */ $contact = new Contact(100, "John"); /* Set your parameters for the request */ $params = array( "Contact" => $contact, "description" => "Barrel of Oil", "amount" => 500, ); /* Invoke webservice method with your parameters, in this case: Function1 */ $response = $client->__soapCall("Function1", array($params)); /* Print webservice response */ var_dump($response); ?> 

Как я знаю, что это работает?

  • Если вы выполняете print_r($params); вы увидите этот результат, поскольку ваш веб-сервис ожидает:

Array ([Contact] => Contact Object ([id] => 100 [name] => John) [description] => Barrel of Oil [amount] => 500)

  • Когда я отлаживал образец .NET webservice, я получил следующее:

введите описание изображения здесь

(Как вы можете видеть, Contact объект не является нулевым, а также другими параметрами, что означает, что ваш запрос был успешно выполнен с PHP-стороны).

  • Ответ от .NET webservice был ожидаемым и показан на стороне PHP:

object (stdClass) [3] public 'Function1Result' => string 'Подробная информация о вашем запросе! id: 100, имя: John, описание: Barrel of Oil, количество: 500 '(длина = 98)


Надеюсь это поможет 🙂

Вы также можете использовать SOAP-сервисы:

 <?php //Create the client object $soapclient = new SoapClient('http://www.webservicex.net/globalweather.asmx?WSDL'); //Use the functions of the client, the params of the function are in //the associative array $params = array('CountryName' => 'Spain', 'CityName' => 'Alicante'); $response = $soapclient->getWeather($params); var_dump($response); // Get the Cities By Country $param = array('CountryName' => 'Spain'); $response = $soapclient->getCitiesByCountry($param); var_dump($response); 

Это пример с реальным сервисом, и он работает.

Надеюсь это поможет.

Сначала инициализируйте веб-службы:

 $client = new SoapClient("http://example.com/webservices?wsdl"); 

Затем установите и передайте параметры:

 $params = array ( "arg0" => $contactid, "arg1" => $desc, "arg2" => $contactname ); $response = $client->__soapCall('methodname', array($params)); 

Обратите внимание, что имя метода доступно в WSDL в качестве имени операции, например:

 <operation name="methodname"> 

Я не знаю, почему мой веб-сервис имеет одинаковую структуру с вами, но ему не нужен класс для параметра, просто массив.

Например: – Мой WSDL:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.kiala.com/schemas/psws/1.0"> <soapenv:Header/> <soapenv:Body> <ns:createOrder reference="260778"> <identification> <sender>5390a7006cee11e0ae3e0800200c9a66</sender> <hash>831f8c1ad25e1dc89cf2d8f23d2af...fa85155f5c67627</hash> <originator>VITS-STAELENS</originator> </identification> <delivery> <from country="ES" node=””/> <to country="ES" node="0299"/> </delivery> <parcel> <description>Zoethout thee</description> <weight>0.100</weight> <orderNumber>10K24</orderNumber> <orderDate>2012-12-31</orderDate> </parcel> <receiver> <firstName>Gladys</firstName> <surname>Roldan de Moras</surname> <address> <line1>Calle General Oraá 26</line1> <line2>(4º izda)</line2> <postalCode>28006</postalCode> <city>Madrid</city> <country>ES</country> </address> <email>gverbruggen@kiala.com</email> <language>es</language> </receiver> </ns:createOrder> </soapenv:Body> </soapenv:Envelope> 

Я var_dump:

 var_dump($client->getFunctions()); var_dump($client->getTypes()); 

Вот результат:

 array 0 => string 'OrderConfirmation createOrder(OrderRequest $createOrder)' (length=56) array 0 => string 'struct OrderRequest { Identification identification; Delivery delivery; Parcel parcel; Receiver receiver; string reference; }' (length=130) 1 => string 'struct Identification { string sender; string hash; string originator; }' (length=75) 2 => string 'struct Delivery { Node from; Node to; }' (length=41) 3 => string 'struct Node { string country; string node; }' (length=46) 4 => string 'struct Parcel { string description; decimal weight; string orderNumber; date orderDate; }' (length=93) 5 => string 'struct Receiver { string firstName; string surname; Address address; string email; string language; }' (length=106) 6 => string 'struct Address { string line1; string line2; string postalCode; string city; string country; }' (length=99) 7 => string 'struct OrderConfirmation { string trackingNumber; string reference; }' (length=71) 8 => string 'struct OrderServiceException { string code; OrderServiceException faultInfo; string message; }' (length=97) 

Так в моем коде:

  $client = new SoapClient('http://packandship-ws.kiala.com/psws/order?wsdl'); $params = array( 'reference' => $orderId, 'identification' => array( 'sender' => param('kiala', 'sender_id'), 'hash' => hash('sha512', $orderId . param('kiala', 'sender_id') . param('kiala', 'password')), 'originator' => null, ), 'delivery' => array( 'from' => array( 'country' => 'es', 'node' => '', ), 'to' => array( 'country' => 'es', 'node' => '0299' ), ), 'parcel' => array( 'description' => 'Description', 'weight' => 0.200, 'orderNumber' => $orderId, 'orderDate' => date('Ym-d') ), 'receiver' => array( 'firstName' => 'Customer First Name', 'surname' => 'Customer Sur Name', 'address' => array( 'line1' => 'Line 1 Adress', 'line2' => 'Line 2 Adress', 'postalCode' => 28006, 'city' => 'Madrid', 'country' => 'es', ), 'email' => 'test.ceres@yahoo.com', 'language' => 'es' ) ); $result = $client->createOrder($params); var_dump($result); 

но это успешно!

прочитай это;-

http://php.net/manual/en/soapclient.call.php

Или

Это хороший пример для функции SOAP «__call». Однако он устарел.

 <?php $wsdl = "http://webservices.tekever.eu/ctt/?wsdl"; $int_zona = 5; $int_peso = 1001; $cliente = new SoapClient($wsdl); print "<p>Envio Internacional: "; $vem = $cliente->__call('CustoEMSInternacional',array($int_zona, $int_peso)); print $vem; print "</p>"; ?> 

Если вы создадите объект SoapParam, это решит вашу проблему. Создайте класс и сопоставьте его с objecttype, заданный WebService, Инициализируйте значения и отправьте запрос. См. Образец ниже.

 struct Contact { function Contact ($pid, $pname) { id = pid; name = pname; } } $struct = new Contact(100,"John"); $soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "Contact","http://soapinterop.org/xsd"); $ContactParam = new SoapParam($soapstruct, "Contact") response = $client->Function1($ContactParam); 

Вам нужно объявить договор класса

 class Contract { public $id; public $name; } $contract = new Contract(); $contract->id = 100; $contract->name = "John"; $params = array( "Contact" => $contract, "description" => "Barrel of Oil", "amount" => 500, ); 

или

 $params = array( $contract, "description" => "Barrel of Oil", "amount" => 500, ); 

затем

 $response = $client->__soapCall("Function1", array("FirstFunction" => $params)); 

или

 $response = $client->__soapCall("Function1", $params); 

Вам нужен многомерный массив, вы можете попробовать следующее:

 $params = array( array( "id" => 100, "name" => "John", ), "Barrel of Oil", 500 ); 

в PHP массив является структурой и очень гибким. Обычно с вызовами мыла я использую оболочку XML так неуверенно, если она будет работать.

РЕДАКТИРОВАТЬ:

То, что вы, возможно, захотите попробовать, это создать json-запрос для отправки или использования этого для создания xml-покупки, следующего за тем, что находится на этой странице: http://onwebdev.blogspot.com/2011/08/php-converting-rss- к json.html