我知道在SO上有很多类似的问题,但我已经尝试过搞乱所有的解决方案而且似乎没有能够使它工作.我试图将xml直接发布到Web服务并获得响应.从技术上讲,我正在尝试连接到freightquote.com,您可以在文档下的
this页右上角找到该文档.我只提到这一点,因为我在他们的xml中看到了很多SOAP这个术语,它可能会有所不同.无论如何我想要的是能够将xml发送到某个网址并获得回复.
$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并得到回复.另外,我需要编码吗?我已经做了很多与Android来回发送xml,但从来没有这样做,但这可能是我问题的一部分.
我目前发送信息的尝试看起来像这样
$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 webservice.这并不难理解.
以下是一些如何分析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 }
<?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(); }
生成的QuoteService.PHP的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>