Отправка xml методом POST

Fedak.o.b

Новичок
Добрый день!

Есть задача!
Получить ответ отправить xml пакет и получить ответ также в формате xml.

Есть даже описание какой POST нужно отправить и какой должен быть ответ.

Вот и сам экземпляр работы!
http://site.com/Remote/Prices.asmx?WSDL
http://site.com/Remote/Prices.asmx?op=GetProducts

Написал скрипт.
Ответ получается:
HTTP/1.1 400 Bad Request Content-Type: text/html Date: Mon, 02 Jul 2012 08:46:48 GMT Connection: close Content-Length: 20
Bad Request

Я не прошу написать код, только указать в каком направление двигается дальше.
 

Fedak.o.b

Новичок
http://site.com/Remote/Prices.asmx?WSDL
http://site.com/Remote/Prices.asmx?op=GetProducts

PHP:
<?php
$request  .= '<?xml version="1.0" encoding="utf-8"?>';
$request  .= '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
$request  .= '<soap:Body>';
$request  .= '<GetProducts xmlns="http://ws.site.com/Remote/">';
$request  .= '<ProductName>33354</ProductName>';
$request  .= '</GetProducts>';
$request  .= '</soap:Body>';
$request  .= '</soap:Envelope>';

$curl_options = array (
  CURLOPT_URL => 'http://site.com/Remote/Prices.asmx?WSDL',
  CURLOPT_POST => TRUE,
  CURLOPT_RETURNTRANSFER => FALSE,
  CURLOPT_HEADER => array(
		'POST /Remote/Remote.asmx HTTP/1.1', 
		'Host: site.com', 
		'Content-Type: text/xml; charset=utf-8', 
		'Content-Length: '.strlen(($request)).'',
		'SOAPAction: "http://ws.site.com/Remote/GetProducts"'
    ),
  CURLOPT_POSTFIELDS => ($request)
  
);
$curl = curl_init() or die("cURL init error");
curl_setopt_array($curl, $curl_options) or die("cURL set options error" . curl_error($curl));
$response = curl_exec($curl) or die ("cURL execute eroor" . curl_error($curl));
print_r($response);
curl_close($curl);
?>
Ответ сервера:
HTTP/1.1 500 Internal Server Error Date: Mon, 02 Jul 2012 16:07:15 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Content-Type: application/soap+xml; charset=utf-8 Content-Length: 509 soap:ReceiverServer was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.1

Описание ответа 500 :
10.5.1 500 Внутренняя ошибка сервера, Internal Server Error.
Сервер столкнулся с непредвиденным условием, которое не позволяет ему выполнить запрос.

А должен быть:
PHP:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetProductsResponse xmlns="http://ws.site.com/Remote/">
      <GetProductsResult>
        <ProductObj>
          <ProductID>long</ProductID>
          <ProductName>string</ProductName>
          <Make>string</Make>
          <Land>string</Land>
          <ActualDate>string</ActualDate>
          <PriceFileName>string</PriceFileName>
          <Delivery>int</Delivery>
          <Delivery2>int</Delivery2>
          <PriceFileDateTime>dateTime</PriceFileDateTime>
        </ProductObj>
        <ProductObj>
          <ProductID>long</ProductID>
          <ProductName>string</ProductName>
          <Make>string</Make>
          <Land>string</Land>
          <ActualDate>string</ActualDate>
          <PriceFileName>string</PriceFileName>
          <Delivery>int</Delivery>
          <Delivery2>int</Delivery2>
          <PriceFileDateTime>dateTime</PriceFileDateTime>
        </ProductObj>
      </GetProductsResult>
    </GetProductsResponse>
  </soap:Body>
</soap:Envelope>
Где я ошибся ?
 

Gremboloid

инженера Гр...
Ошибку не до конца прочитал. Там написано что ReceiverServer не смог обработать запрос. ---> Данные на корневом уровне является неправильными. строка 1, позиция 1,1
Не проще ли в данной ситуации воспользоваться уже готовым инструментом?
Практическое использование SOAP в PHP 5.
 

Fedak.o.b

Новичок
Пробовал soap.

По документации нужно отправить:
PHP:
POST /Remote/Prices.asmx HTTP/1.1
Host: site.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://ws.site.com/Remote/GetProducts"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetProducts xmlns="http://ws.site.com/Remote/">
      <ProductName>string</ProductName>
    </GetProducts>
  </soap:Body>
</soap:Envelope>
Написал скрипт:
PHP:
<?
$client2 = new SoapClient('http://site.com/Remote/Prices.asmx?WSDL', array('trace' => 1));
$result = $client2->GetProducts(array('ProductName' => '453453'));

var_dump($result->out);
echo $client2->__getLastRequest();
echo $client2->__getLastResponse();

var_dump($client2->__getFunctions());
?>
Ошибка:
Fatal error: Uncaught SoapFault exception: [soap:Client] You must login before using this function! in /home/gent/test.in.ua/www/soap.php:3 Stack trace: #0 /home/gent/test.in.ua/www/soap.php(3): SoapClient->__call('GetProducts', Array) #1 /home/gent/test.in.ua/www/soap.php(3): SoapClient->GetProducts(Array) #2 {main} thrown in /home/gent/test.in.ua/www/soap.php on line 3
 

AlexMc

Новичок
Попробую вставить свои 5 копеек :
Изначально задача стояла - получить данные с сервера, используя Soap/WSDL
Я в таких случаях поступаю немного по другому.
Снимаю доступный wsdl код - он, как правило, по ссылке с окончанием ?WSDL
полученный файл пропускаю через обработчик, который на выходе мне дает класс с доступа к самому серверу
и класс с описанием всех методов, доступных через WSDL

В простейшем случае доступ поднимается максимум за час, при этом я получаю доступ сразу ко всем методам,
описанным в WSDL
Бывают ситуации, когда базовый WSDL содержит инклюды с дополнительными описаниями. Их тоже нужно отрабатывать
При наличии авторизации при доступе к сервису в классе доступа все правится 2 строками - базовая спецификация
рассчитана на доступ без пароля - такая, например, у Банка России или у СберБанка - для получения курсов валют и уймы всего еще чего.

А дальнейшая работа сводится с составлению цепочки вызовов примерно в таком ключе :

// Это тестовый доступ к Росно - страховщику для онлайн страхования

$client = new PoshoWebServiceConnector (app-test.ibpost.ru:81/SOAP?service=InsureTravel); // само подключение

$session = '11460 2147297189'; // сама сессия получается отдельным методом - здесь просто упрощение

$request = new PoshoInsureTravel___WS_GetCountries(); // этот вызов вернет объект со списком доступных стран
$request->Session = $session;
$countries = $client->WS_GetCountries($request);

$request = new PoshoInsureTravel___WS_GetSumma(); // а этот вызов вернет объект с возможными страховыми суммами
$request->Session = $session;
$request->Country = $countries->Countries->CTCountry[120]->NAME;
$summ = $client->WS_GetSumma($request);

То есть видно, насколько дальнейшая работа с Soap удобна, когда все классы ( а здесь это PoshoInsureTravel___WS_GetSumma, PoshoInsureTravel___WS_GetCountries, PoshoWebServiceConnector ) уже определены. Ну и никто не мешает добавлять в код обработку
исключений, на тот случай, если ответ от сервера ошибочный

Готов при интересе расписать как автоматически парсить WSDL - но там материал очень большой, за этим лучше лично - на скайп McCoushev
 

alekciy

Новичок
но там материал очень большой, за этим лучше лично - на скайп McCoushev
Если материал большой, то это должна быть статья (на том же хабре), но точно не скайп. А если лично по скайпу... материал на звание большого значит не тянет.
 

AlexMc

Новичок
Я не материал по скайпу передавать собирался, а объяснить конкретные моменты. А для каждого WSDL они разные.
А статью писать - просто духу не хватит, да и со временем не очень.
 
Сверху