Я знаю, что на SO есть какое-то количество подобных вопросов, но я попытался объединиться со всеми решениями и, похоже, не смог заставить его работать. Я пытаюсь отправить xml прямо в веб-службу и получить ответ. Технически я пытаюсь подключиться к фреймворку, документации, для которой вы можете найти в правом верхнем углу этой страницы в документации. Я только упоминаю об этом, потому что я много знаю, что термин SOAP очень много в их xml, и это может иметь значение. Во всяком случае, я хочу, чтобы отправить xml на какой-то URL-адрес и получить ответ.
Поэтому, если бы у меня было следующее
$xml = "<?xml version='1.0' encoding='utf-8'?> <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'> <soap:Body> <GetRatingEngineQuote xmlns='http://tempuri.org/'> <request> <CustomerId>0</CustomerId> <!-- Identifier for customer provided by Freightquote --> <QuoteType>B2B</QuoteType> <!-- B2B / eBay /Freightview --> <ServiceType>LTL</ServiceType> <!-- LTL / Truckload / Groupage / Haulage / Al --> <QuoteShipment> <IsBlind>false</IsBlind> <PickupDate>2010-09-13T00:00:00</PickupDate> <SortAndSegregate>false</SortAndSegregate> <ShipmentLocations> <Location> <LocationType>Origin</LocationType> <RequiresArrivalNotification>false</RequiresArrivalNotification> <HasDeliveryAppointment>false</HasDeliveryAppointment> <IsLimitedAccess>false</IsLimitedAccess> <HasLoadingDock>false</HasLoadingDock> <IsConstructionSite>false</IsConstructionSite> <RequiresInsideDelivery>false</RequiresInsideDelivery> <IsTradeShow>false</IsTradeShow> <IsResidential>false</IsResidential> <RequiresLiftgate>false</RequiresLiftgate> <LocationAddress> <PostalCode>30303</PostalCode> <CountryCode>US</CountryCode> </LocationAddress> <AdditionalServices /> </Location> <Location> <LocationType>Destination</LocationType> <RequiresArrivalNotification>false</RequiresArrivalNotification> <HasDeliveryAppointment>false</HasDeliveryAppointment> <IsLimitedAccess>false</IsLimitedAccess> <HasLoadingDock>false</HasLoadingDock> <IsConstructionSite>false</IsConstructionSite> <RequiresInsideDelivery>false</RequiresInsideDelivery> <IsTradeShow>false</IsTradeShow> <IsResidential>false</IsResidential> <RequiresLiftgate>false</RequiresLiftgate> <LocationAddress> <PostalCode>60606</PostalCode> <CountryCode>US</CountryCode> </LocationAddress> <AdditionalServices /> </Location> </ShipmentLocations> <ShipmentProducts> <Product> <Class>55</Class> <Weight>1200</Weight> <Length>0</Length> <Width>0</Width> <Height>0</Height> <ProductDescription>Books</ProductDescription> <PackageType>Pallets_48x48</PackageType> <IsStackable>false</IsStackable> <DeclaredValue>0</DeclaredValue> <CommodityType>GeneralMerchandise</CommodityType> <ContentType>NewCommercialGoods</ContentType> <IsHazardousMaterial>false</IsHazardousMaterial> <PieceCount>5</PieceCount> <ItemNumber>0</ItemNumber> </Product> </ShipmentProducts> <ShipmentContacts /> </QuoteShipment> </request> <user> <Name>someone@something.com</Name> <Password>password</Password> </user> </GetRatingEngineQuote> </soap:Body> </soap:Envelope>";
(Я отредактировал это, чтобы содержать мой фактический xml, поскольку он может предоставить некоторую перспективу
Я хочу отправить его на сайт http://www.someexample.com и получить ответ. Кроме того, мне нужно его кодировать? Я много раз отправлял xml туда и обратно с Android, и мне никогда не приходилось это делать, но это могло быть частью моей проблемы.
Моя попытка отправить информацию в настоящее время выглядит следующим образом:
$xml_post_string = 'XML='.urlencode($xml->asXML()); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://b2b.Freightquote.com/WebService/QuoteService.asmx'); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); curl_close($ch);
Если вы ходите по сервисам SOAP, я настоятельно рекомендую вам изучить основы один раз, а затем использовать этот отличный инструмент снова и снова. Есть много возможностей, которые вы можете использовать, или вы будете изобретать колесо и пытаться генерировать xml-файлы, анализировать xml-файлы, ошибки и т. Д. Используйте подготовленные инструменты, и ваша жизнь будет проще, а ваш код лучше (меньше ошибок).
Посмотрите http://www.php.net/manual/en/soapclient.soapcall.php#example-5266, как использовать веб- сервис SOAP. Это не так сложно понять.
Вот какой код вы можете анализировать webserivce. Затем создавайте типы карт для классов и просто отправляйте и получайте php-объекты. Вы можете найти инструмент для автоматического создания классов ( http://www.urdalen.no/wsdl2php/manual.php ).
<?php try { $client = new SoapClient('http://b2b.freightquote.com/WebService/QuoteService.asmx?WSDL'); // read function list $funcstions = $client->__getFunctions(); var_dump($funcstions); // read some request obejct $response = $client->__getTypes(); var_dump($response); } catch (SoapFault $e) { // do some service level error stuff } catch (Exception $e) { // do some application level error stuff }
Если вы будете использовать инструмент генерации wsdl2php, все будет очень просто:
<?php require_once('./QuoteService.php'); try { $client = new QuoteService(); // create request $tracking = new TrackingRequest(); $tracking->BOLNumber = 67635735; $request = new GetTrackingInformation(); $request->request = $tracking; // send request $response = $client->GetTrackingInformation($request); var_dump($response); } catch (SoapFault $e) { // do some service level error stuff echo 'Soap fault ' . $e->getMessage(); } catch (Exception $e) { // do some application level error stuff echo 'Error ' . $e->getMessage(); }
Сгенерированный PHP-код для QuoteService.php
вы можете посмотреть здесь: http://pastie.org/8165331
Это захваченное сообщение:
Запрос
POST /WebService/QuoteService.asmx HTTP/1.1 Host: b2b.freightquote.com Connection: Keep-Alive User-Agent: PHP-SOAP/5.4.17 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://tempuri.org/GetTrackingInformation" Content-Length: 324 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"> <SOAP-ENV:Body> <ns1:GetTrackingInformation> <ns1:request> <ns1:BOLNumber>67635735</ns1:BOLNumber> </ns1:request> </ns1:GetTrackingInformation> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
отклик
HTTP/1.1 200 OK Date: Mon, 22 Jul 2013 21:46:06 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 660 Set-Cookie: BIGipServerb2b_freightquote_com=570501130.20480.0000; path=/ <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <GetTrackingInformationResponse xmlns="http://tempuri.org/"> <GetTrackingInformationResult> <BOLNumber>0</BOLNumber> <EstimatedDelivery>0001-01-01T00:00:00</EstimatedDelivery> <TrackingLogs /> <ValidationErrors> <B2BError> <ErrorType>Validation</ErrorType> <ErrorMessage>Unable to find shipment with BOL 67635735.</ErrorMessage> </B2BError> </ValidationErrors> </GetTrackingInformationResult> </GetTrackingInformationResponse> </soap:Body> </soap:Envelope>
Во-первых, если ваш код написан так, я сомневаюсь, что это может быть причиной кавычек … Вы должны использовать двойную цитату вокруг вашего xml:
$my_xml = "<?xml version='1.0' standalone='yes'?> <user> <Name>xmltest@freightquote.com</Name> <Password>XML</Password> </user>";
Кроме того, вы можете использовать плакат , аддон firefox (возможно, эквивалент на хроме), чтобы помочь вам с вашими запросами, особенно если вы используете WebServices. Таким образом, вы сможете увидеть, является ли ошибка серверной или клиентской стороной.
Это должно помочь вам отладить.
Я использую этот сценарий командной строки для проверки вызова SOAP:
#!/usr/bin/php <?php //file client-test.php $xml_data = file_get_contents('php://stdin'); $ch = curl_init('http://example.com/server/'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_HTTPHEADER, array('SOAPAction', 'MySoapAction')); 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);
Такое использование (в командной строке): $ client-test.php < yourSoapEnveloppe.xml
В этом примере файл yourSoapEnveloppe.xml
является содержимым переменной $xml
.
Вы можете использовать stream_context_create
и file_get_contents
для отправки xml в сообщении.
$xml = "<your_xml_string>"; $send_context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/xml', 'content' => $xml ) )); print file_get_contents($url, false, $send_context);