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

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

Вот хороший пример: stackoverflow.com/questions/7120586/soap-request-in-php

Iladarsda 24.08.2011 12:22

Вы смотрели документацию php.net? Запускаем здесь а точнее <s> здесь </s>

Keltia 23.01.2009 01:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
54
2
172 435
7

Ответы 7

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

Небольшой пример кода из первой ссылки:

<?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 SOAP не работал с сервером SOAP на основе .NET, который нам пришлось использовать. Он пожаловался на недопустимое определение схемы. Хотя .NET-клиент отлично работал с этим сервером. Между прочим, позвольте мне заявить, что совместимость SOAP - это миф.

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

Затем мы решили использовать 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 позволил нам сократить время запросов SOAP более чем на 30%. И с тех пор мы перенаправляем все жалобы на производительность серверам.

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

Что должна содержать строка $ REQUEST_BODY, можете ли вы добавить это в пример кода?

SlickRemix 17.04.2019 19:34

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

$client = new SoapClient($url);

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

$client->__getTypes();      
$client->__getFunctions();  

$result = $client->functionName();  

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

$url - это URL-адрес файла WSDL?

HartleySan 27.12.2016 23:59

@HartleySan да

hamada147 18.08.2018 22:36

@HartleySan - это параметры, передаваемые в функции, должны быть в массиве или xml?

Jimmy.B 17.09.2020 16:31

Jimmy.B, прошло много времени с тех пор, как я использовал SOAP, но я помню, что это должен быть массив, и все это автоматически конвертируется для вас.

HartleySan 17.09.2020 17:56

А что если WSDL-файл за авторизацией? stackoverflow.com/questions/66707432/…

user164863 20.03.2021 14:39

Мне нужно было сделать много очень простых 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);

Ниже приведен быстрый пример того, как это сделать (который лучше всего объяснил мне проблему), который я, по сути, нашел в этот сайт. Эта ссылка на веб-сайт также объясняет 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/

Если у XML есть идентификаторы с одинаковыми именами на разных уровнях, есть решение. Вам не обязательно отправлять необработанный XML (этот объект PHP SOAP не позволяет отправлять RAW XML), поэтому вы всегда должны переводить свой XML в массив, как в примере ниже:

$originalXML = "
<xml>
  <firstClient>
      <name>someone</name>
      <adress>R. 1001</adress>
  </firstClient>
  <secondClient>
      <name>another one</name>
      <adress></adress>
  </secondClient>
</xml>"

//Translate the XML above in a array, like PHP SOAP function requires
$myParams = array('firstClient' => array('name' => 'someone',
                                  'adress' => 'R. 1001'),
            'secondClient' => array('name' => 'another one',
                                  'adress' => ''));

$webService = new SoapClient($someURL);
$result = $webService->someWebServiceFunction($myParams);

или же

$soapUrl = "http://privpakservices.schenker.nu/package/package_1.3/packageservices.asmx?op=SearchCollectionPoint";

$xml_post_string = '<?xml version = "1.0" encoding = "utf-8"?><soap12:Envelope xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" xmlns:soap12 = "http://www.w3.org/2003/05/soap-envelope"><soap12:Body><SearchCollectionPoint xmlns = "http://privpakservices.schenker.nu/"><customerID>XXX</customerID><key>XXXXXX-XXXXXX</key><serviceID></serviceID><paramID>0</paramID><address>RiksvŠgen 5</address><postcode>59018</postcode><city>Mantorp</city><maxhits>10</maxhits></SearchCollectionPoint></soap12:Body></soap12:Envelope>';

$headers = array(
"POST /package/package_1.3/packageservices.asmx HTTP/1.1",
"Host: privpakservices.schenker.nu",
"Content-Type: application/soap+xml; charset=utf-8",
"Content-Length: ".strlen($xml_post_string)
); 

$url = $soapUrl;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($ch); 
curl_close($ch);

$response1 = str_replace("<soap:Body>","",$response);
$response2 = str_replace("</soap:Body>","",$response1);

$parser = simplexml_load_string($response2);

+1 для части длины содержимого переменной $ headers. кроме того, вы можете добавить одну вещь: «SOAPAction: xxxx.xxx.com/xxxxx»

Shuvro 22.02.2019 21:48

Другие вопросы по теме