【问题标题】:Extract data from cURL response keeps returning no value从 cURL 响应中提取数据一直没有返回值
【发布时间】:2014-06-23 10:35:22
【问题描述】:

我想达到什么目的:我想从网络服务器获得响应。有了这个回复,我有一些需要提取的数据。我已经到了可以接收来自网络服务的响应的地步了。

问题是什么:我使用 cURL 从服务器获得数据响应,但我无法从答案中提取数据,因为它总是返回一个空值。

我尝试了什么: 我试图在一个数组中解析结果(没有返回值) 我试图用新的 SimpleXMLElement (空对象)解析结果 我尝试使用 JSON 对其进行编码,然后再次对其进行解码(空数组) 我试图爆炸结果(返回没有好的值)

我不知道该怎么办了,有人可以看看。

我的 cURL 代码:

$xml = '
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://dpd.com/common/service/types/Authentication/2.0" xmlns:ns1="http://dpd.com/common/service/types/ShipmentService/3.1"> 
    <soapenv:Header> 
        <ns:authentication> 
            <delisId>'.$delisId.'</delisId> 
            <authToken>'.$auth_token.'</authToken> 
            <messageLanguage>'.$messageLanguage.'</messageLanguage> 
        </ns:authentication> 
    </soapenv:Header> 
    <soapenv:Body> 
        <ns1:storeOrders> 
            <printOptions> 
                <printerLanguage>'.$printerLanguage.'</printerLanguage> 
                <paperFormat>'.$paperFormat.'</paperFormat> 
            </printOptions> 
            <order> 
                <generalShipmentData> 
                    <identificationNumber>'.$identificationNumber.'</identificationNumber> 
                    <sendingDepot>'.$sendingDepot.'</sendingDepot> 
                    <product>'.$product.'</product> 
                    <mpsCompleteDelivery>'.$mpsCompleteDelivery.'</mpsCompleteDelivery> 
                    <sender> 
                        <name1>'.$send_name.'</name1> 
                        <street>'.$send_street.'</street> 
                        <country>'.$send_country.'</country> 
                        <zipCode>'.$send_zipcode.'</zipCode> 
                        <city>'.$send_city.'</city> 
                        <customerNumber>'.$send_customerNumber.'</customerNumber> 
                    </sender> 
                    <recipient> 
                        <name1>'.$rec_name.'</name1> 
                        <street>'.$rec_street.'</street> 
                        <state>'.$rec_state.'</state> 
                        <country>'.$rec_country.'</country> 
                        <zipCode>'.$rec_zipcode.'</zipCode> 
                        <city>'.$rec_city.'</city> 
                    </recipient> 
                </generalShipmentData> 
                <parcels> 
                    <parcelLabelNumber>'.$parcelLabelNumber.'</parcelLabelNumber> 
                </parcels> 
                <productAndServiceData> 
                    <orderType>'.$orderType.'</orderType> 
                </productAndServiceData> 
            </order> 
        </ns1:storeOrders> 
    </soapenv:Body> 
</soapenv:Envelope>
    ';

    $headers = array(
        "POST  HTTP/1.1",
        "Content-type: application/soap+xml; charset=\"utf-8\"",
        "SOAPAction: \"http://dpd.com/common/service/ShipmentService/3.1/storeOrders\"",
        "Content-length: ".strlen($xml)
    );

    $url = 'https://public-ws-stage.dpd.com/services/ShipmentService/V3_1/';

    $cl = curl_init();
    curl_setopt($cl, CURLOPT_URL, $url);
    curl_setopt($cl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($cl, CURLOPT_POST, 1);
    curl_setopt($cl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($cl, CURLOPT_POSTFIELDS, "$xml");
    curl_setopt($cl, CURLOPT_RETURNTRANSFER, 1);
    $output_cl = curl_exec($cl);
    curl_close($cl);

    //return $output_cl;


    $output_xml = new SimpleXMLElement($output_cl);

    foreach($output_xml->orderresult as $orderresult)
    {
        foreach($orderresult->parcellabelspdf as $pdf)
        {
            return $pdf;
        }
    }

来自服务器的响应(我认为是字符串格式,但不确定):

<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:body>
        <ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
            <orderresult>
                <parcellabelspdf>pdflabel</parcellabelspdf>
                <shipmentresponses>
                    <identificationnumber>idnumber</identificationnumber>
                    <mpsid>mpsid</mpsid>
                    <parcelinformation>
                        <parcellabelnumber>labelnumber</parcellabelnumber>
                    </parcelinformation>
                </shipmentresponses>
            </orderresult>
        </ns2:storeordersresponse>
    </soap:body>
</soap:envelope>

我想提取 parcellabelspdf 值和 mpsid 值。

【问题讨论】:

  • 我假设代码的第二部分是您从echo $output_cl; 获得的代码。如果没有,请给出echo的输出
  • @Athafoud 是的,这确实是 echo 的输出
  • 你为什么还不使用SoapClient?
  • @Jack 我一开始尝试使用 SoapClient,但我得到了一个主要的异常错误,没有更多的错误细节。所以我尝试使用 cURL 代替。但现在一切正常。感谢大家的帮助!

标签: php xml json curl wsdl


【解决方案1】:

尝试使用DOMDocument

$doc = new DOMDocument();
$doc->loadXML($output_cl);

$mpsid = $doc->getElementsByTagName( "mpsid" );
$mpsid_value= $mpsid->item(0)->nodeValue;

【讨论】:

  • 我只是尝试了您的解决方案,但仍然没有返回值。
  • 所以我认为你在解析信封时可能会出错。检查您的语法并尝试var_dump($doc) 以查看字符串是否正确加载。
  • 如果我在你写的行之后使用 var_dump($doc),我会得到以下响应:object(DOMDocument)#2 (0) { }。我检查了我所有的语法是否有错误,但我找不到一个。也许你能找到一个。 var dump 的响应好不好?
  • var_dump() 的结果不好。另外,正如我所见,您的响应信封格式正确。我唯一能想到的是你有解析错误。您是否将您的 php 配置设置为显示所有错误和警告?
  • 是的,它显示了所有内容,我什至现在尝试将响应放在一个字符串中,而无需从 web 服务调用它,然后将其解析为一个对象。但这也返回一个空对象。您能否发布一个示例,说明如何将字符串转换为对象并引用其节点?
【解决方案2】:

这是一个带注释的代码示例。您基本上很难理解如何访问命名空间。我的示例显示了这种冗长(我还建议您在自己构建它时,在两者之间使用-&gt;asXML() 来调试您已经走了多远)。

<?php
/*
 * @link https://stackoverflow.com/questions/24363786/extract-data-from-curl-response-keeps-returning-no-value
 */

$buffer = <<<XML
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:body>
        <ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
            <orderresult>
                <parcellabelspdf>pdflabel</parcellabelspdf>
                <shipmentresponses>
                    <identificationnumber>idnumber</identificationnumber>
                    <mpsid>mpsid</mpsid>
                    <parcelinformation>
                        <parcellabelnumber>labelnumber</parcellabelnumber>
                    </parcelinformation>
                </shipmentresponses>
            </orderresult>
        </ns2:storeordersresponse>
    </soap:body>
</soap:envelope>
XML;


$xml = simplexml_load_string($buffer);

// into <soap:*> namespace
$body        = $xml->children('soap', true)->body;

// into <ns2:*> namespace
$storeordersresponse = $body->children('ns2', true)->storeordersresponse;

// into document default namespace (no namespace)
$orderresult = $storeordersresponse->children()->orderresult; 

// you can now traverse as usual as you've reached the <orderresult> element
$mpsid       = $orderresult->shipmentresponses->mpsid;

echo $mpsid->asXML(); // prints "<mpsid>mpsid</mpsid>"

如果您不想在您的代码中进行所有遍历,并且您已经对命名空间的工作方式有所了解,那么这里有一个古老但非常有用的问答。它介绍了 XPath,它可以让你省去很多打字:

【讨论】:

  • 对,或者你……使用 SoapClient :P
猜你喜欢
  • 2021-07-29
  • 1970-01-01
  • 2022-01-17
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
相关资源
最近更新 更多