简体   繁体   English

通过邮件发送XML与PHP

[英]Send XML with php via post

I know there are any number of similar questions to this on SO, but I've tried messing around with all the solutions and haven't seemed to be able to make it work. 我知道在SO上有很多类似的问题,但我已经尝试过搞乱所有的解决方案而且似乎没有能够使它工作。 I am trying to post xml directly to a web service and get a response back. 我试图将xml直接发布到Web服务并获得响应。 Technically I am trying to connect to freightquote.com, the documentation for which you can find in the upper right hand corner of this page under documentation. 从技术上讲,我正在尝试连接到freightquote.com,您可以在本页右上角的文档下找到文档。 I only mention that because I see the term SOAP a lot in their xml and it might make a difference. 我只提到这一点,因为我在他们的xml中看到了很多SOAP这个术语,它可能会有所不同。 Anyway what I want is the ability to send xml to some url and get a response back. 无论如何我想要的是能够将xml发送到某个网址并获得回复。

So if I had the following 所以如果我有以下内容

$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>";

(I edited this to contain my actual xml since it may lend some perspective (我编辑它以包含我的实际xml,因为它可能提供一些观点

I'd want to send it to http://www.someexample.com and get a response. 我想将它发送到http://www.someexample.com并得到回复。 Also, do I need to encode it? 另外,我需要编码吗? I've done a lot of sending xml back and forth with android, and never had to but that might be part of my problem. 我已经做了很多与Android来回发送xml,但从来没有这样做,但这可能是我问题的一部分。

My attempt to send the information currently looks like this 我目前发送信息的尝试看起来像这样

$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);

If you are walking around SOAP services, I strongly recommend you to learn basics once, and then use this great tool again and again. 如果您正在使用SOAP服务,我强烈建议您一次学习基础知识,然后一次又一次地使用这个伟大的工具。 There are many features you can just use, or you will be reinventing the wheel and struggling with generating xml files, parsing xml files, faults etc. Use prepared tools and your life will be easier and your code better (less bugs). 您可以使用许多功能,或者您将重新发明轮子并努力生成xml文件,解析xml文件,故障等。使用准备好的工具,您的生活将更容易,您的代码更好(更少的错误)。

Look at http://www.php.net/manual/en/soapclient.soapcall.php#example-5266 how to consume SOAP webservice. 请查看http://www.php.net/manual/en/soapclient.soapcall.php#example-5266如何使用SOAP Web服务。 It is not so hard to understand. 这并不难理解。

Here is some code how you can analyze webserivce. 以下是一些如何分析webserivce的代码。 Then map types to classes and just send and receive php objects. 然后将类型映射到类,只发送和接收php对象。 You can look for some tool to generate classes automatically ( http://www.urdalen.no/wsdl2php/manual.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
}

If you will use wsdl2php generating tool, everything is very easy: 如果您将使用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();
}

Generated php code for QuoteService.php you can see here: http://pastie.org/8165331 QuoteService.php生成的php代码,你可以在这里看到: http//pastie.org/8165331

This is captured communication: 这是捕获的通信:

Request 请求

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>

Response 响应

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>

First, if your code is written like this, I doubt this works be cause of the quotes... You should use double quote around your xml: 首先,如果您的代码是这样编写的,我怀疑这是引用的原因...您应该在xml周围使用双引号:

$my_xml = "<?xml version='1.0' standalone='yes'?>
           <user> 
               <Name>xmltest@freightquote.com</Name> 
               <Password>XML</Password> 
           </user>";

Also, you could use poster , a firefox addon (there is probably the equivalent on chrome), to help you with your requests, especially if you use WebServices. 此外,您可以使用海报 ,一个firefox插件(可能还有相应的chrome)来帮助您处理请求,尤其是在您使用WebServices时。 That way, you will be able to see if the error is server-side or client-side. 这样,您将能够查看错误是服务器端还是客户端。

This should help you debugging. 这应该可以帮助您调试。

I use this command-line script to test SOAP call: 我使用此命令行脚本来测试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);

Usage like this (in command line) : $ client-test.php < yourSoapEnveloppe.xml 像这样的用法(在命令行中): $ client-test.php < yourSoapEnveloppe.xml

In this example the yourSoapEnveloppe.xml file is the content of your $xml variable. 在此示例中, yourSoapEnveloppe.xml文件是$xml变量的内容。

You can use stream_context_create and file_get_contents to send xml in post. 您可以使用stream_context_createfile_get_contents在post中发送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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM