Я привык писать 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 с данными:
Какой будет правильный синтаксис? Я пробовал всевозможные варианты, но кажется, что мыльная структура довольно гибкая, поэтому есть очень много способов сделать это. Не удалось понять это из руководства …
ОБНОВЛЕНИЕ 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, );
Ошибка в обоих случаях: объект не имеет свойства «Контакт»
Просто, чтобы знать, я пытался воссоздать вашу ситуацию …
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)
(Как вы можете видеть, Contact
объект не является нулевым, а также другими параметрами, что означает, что ваш запрос был успешно выполнен с 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