Как отправить запрос SOAP из PHP

Кто-нибудь знает, как я могу отправить SOAP-запрос из PHP?

По моему опыту, это не так просто. Встроенный PHP SOAP-клиент не работал с SOAP-сервером .NET, который нам приходилось использовать. Он жаловался на неверное определение схемы. Хотя клиент .NET работал с этим сервером просто отлично. Кстати, позвольте мне утверждать, что SOAP-совместимость – это миф.

Следующим шагом был NuSOAP . Это работало довольно долгое время. Кстати, ради бога, не забывайте кэшировать WSDL! Но даже с пользователями, кэшированными WSDL, жаловался, что эта чертовская вещь медленная.

Затем мы решили SimpleXMLElemnt с HTTP, собрать запросы и прочитать ответы с помощью SimpleXMLElemnt , например:

 $request_info = array(); $full_response = @http_post_data( 'http://example.com/OTA_WS.asmx', $REQUEST_BODY, array( 'headers' => array( 'Content-Type' => 'text/xml; charset=UTF-8', 'SOAPAction' => 'HotelAvail', ), 'timeout' => 60, ), $request_info ); $response_xml = new SimpleXMLElement(strstr($full_response, '<?xml')); foreach ($response_xml->xpath('//@HotelName') as $HotelName) { echo strval($HotelName) . "\n"; } 

Обратите внимание, что в PHP 5.2 вам понадобится pecl_http, поскольку (сюрприз-сюрприз!) Нет HTTP-клиента, встроенного.

Переход на голый HTTP помог нам получить более 30% запросов SOAP. И с этого момента мы перенаправляем всю производительность, жалуясь на серверных парней.

В конце концов, я бы рекомендовал этот последний подход, а не из-за производительности. Я думаю, что в общем, на динамическом языке, таком как PHP, нет никакой пользы от всего этого WSDL / type-control. Вам не нужна фантастическая библиотека для чтения и записи XML, со всем этим созданием заглушек и динамическими прокси. Ваш язык уже динамичен, а SimpleXMLElement работает просто отлично и так прост в использовании. Кроме того, у вас будет меньше кода , что всегда хорошо.

PHP поддерживает SOAP. Просто позвони

 $client = new SoapClient($url); 

для подключения к SoapServer, а затем вы можете получить список функций и функций вызова, просто сделав …

 $client->__getTypes(); $client->__getFunctions(); $result = $client->functionName(); 

для более http://www.php.net/manual/en/soapclient.soapclient.php

Мне нужно было сделать очень простые XML-запросы и после прочтения комментария @Ivan Krechetov о быстром ударе SOAP, я попробовал его код и обнаружил, что http_post_data () не встроен в PHP 5.2. Не очень хочу установить его, я попробовал cURL, который находится на всех моих серверах. Хотя я не знаю, насколько быстро cURL сравнивается с SOAP, было бы легко сделать то, что мне было нужно. Ниже приведен образец с cURL для тех, кому это нужно.

 $xml_data = '<?xml version="1.0" encoding="UTF-8" ?> <priceRequest><customerNo>123</customerNo><password>abc</password><skuList><SKU>99999</SKU><lineNumber>1</lineNumber></skuList></priceRequest>'; $URL = "https://test.testserver.com/PriceAvailability"; $ch = curl_init($URL); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "$xml_data"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); print_r($output); 

Вы можете посмотреть здесь и здесь .

Маленький пример кода из первой ссылки:

 <?php // include the SOAP classes require_once('nusoap.php'); // define parameter array (ISBN number) $param = array('isbn'=>'0385503954'); // define path to server application $serverpath ='http://services.xmethods.net:80/soap/servlet/rpcrouter'; //define method namespace $namespace="urn:xmethods-BNPriceCheck"; // create client object $client = new soapclient($serverpath); // make the call $price = $client->call('getPrice',$param,$namespace); // if a fault occurred, output error info if (isset($fault)) { print "Error: ". $fault; } else if ($price == -1) { print "The book is not in the database."; } else { // otherwise output the result print "The price of book number ". $param[isbn] ." is $". $price; } // kill object unset($client); ?> с <?php // include the SOAP classes require_once('nusoap.php'); // define parameter array (ISBN number) $param = array('isbn'=>'0385503954'); // define path to server application $serverpath ='http://services.xmethods.net:80/soap/servlet/rpcrouter'; //define method namespace $namespace="urn:xmethods-BNPriceCheck"; // create client object $client = new soapclient($serverpath); // make the call $price = $client->call('getPrice',$param,$namespace); // if a fault occurred, output error info if (isset($fault)) { print "Error: ". $fault; } else if ($price == -1) { print "The book is not in the database."; } else { // otherwise output the result print "The price of book number ". $param[isbn] ." is $". $price; } // kill object unset($client); ?> 

Ниже приведен краткий пример того, как это сделать (что лучше всего объясняет мне вопрос), который я, по сути, нашел на этом веб-сайте . Эта ссылка на сайт также объясняет WSDL, что важно для работы с SOAP-сервисами.

Тем не менее, я не думаю, что API-адрес, который они использовали в приведенном ниже примере, все еще работает, поэтому просто переключитесь на один из своих собственных вариантов.

 $wsdl = 'http://terraservice.net/TerraService.asmx?WSDL'; $trace = true; $exceptions = false; $xml_array['placeName'] = 'Pomona'; $xml_array['MaxItems'] = 3; $xml_array['imagePresence'] = true; $client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions)); $response = $client->GetPlaceList($xml_array); var_dump($response); 

Мы можем использовать библиотеку PHP cURL для генерации простого HTTP-запроса POST. В следующем примере показано, как создать простой запрос SOAP с использованием cURL.

Создайте soap-server.php, которые записывают SOAP-запрос в soap-request.xml в веб-папку.

 We can use the PHP cURL library to generate simple HTTP POST request. The following example shows you how to create a simple SOAP request using cURL. Create the soap-server.php which write the SOAP request into soap-request.xml in web folder. <?php $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $f = fopen("./soap-request.xml", "w"); fwrite($f, $HTTP_RAW_POST_DATA); fclose($f); ?> The next step is creating the soap-client.php which generate the SOAP request using the cURL library and send it to the soap-server.php URL. <?php $soap_request = "<?xml version=\"1.0\"?>\n"; $soap_request .= "<soap:Envelope xmlns:soap=\"http://www.w3.org/2001/12/soap-envelope\" soap:encodingStyle=\"http://www.w3.org/2001/12/soap-encoding\">\n"; $soap_request .= " <soap:Body xmlns:m=\"http://www.example.org/stock\">\n"; $soap_request .= " <m:GetStockPrice>\n"; $soap_request .= " <m:StockName>IBM</m:StockName>\n"; $soap_request .= " </m:GetStockPrice>\n"; $soap_request .= " </soap:Body>\n"; $soap_request .= "</soap:Envelope>"; $header = array( "Content-type: text/xml;charset=\"utf-8\"", "Accept: text/xml", "Cache-Control: no-cache", "Pragma: no-cache", "SOAPAction: \"run\"", "Content-length: ".strlen($soap_request), ); $soap_do = curl_init(); curl_setopt($soap_do, CURLOPT_URL, "http://localhost/php-soap-curl/soap-server.php" ); curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($soap_do, CURLOPT_TIMEOUT, 10); curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true ); curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($soap_do, CURLOPT_POST, true ); curl_setopt($soap_do, CURLOPT_POSTFIELDS, $soap_request); curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header); if(curl_exec($soap_do) === false) { $err = 'Curl error: ' . curl_error($soap_do); curl_close($soap_do); print $err; } else { curl_close($soap_do); print 'Operation completed without any errors'; } ?> Enter the soap-client.php URL in browser to send the SOAP message. If success, Operation completed without any errors will be shown and the soap-request.xml will be created. <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.example.org/stock"> <m:GetStockPrice> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope> Original - http://eureka.ykyuen.info/2011/05/05/php-send-a-soap-request-by-curl/