PHP - 如何获得curl响应的特定值

时间:2015-11-03 08:45:24

标签: php xml curl xml-parsing

我使用curl方法从API获取响应。它确实返回了一个xml响应。

响应返回一组字符串,我无法获得我想要的确切值。

这些是我的代码:

$url = 'someurlwithGETparameter';

$ch = curl_init();

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);

curl_close($ch);

例如:

< foods >
     < chinese > Shark Fin </ chinese>
     < japanese > Sushi </ japanese>
< /foods >

我想获得中国食物“鲨鱼鳍”并把它放在一个变量中。

$chineseFood = $somethinglike['chinese'];

所以当我回应$ chineseFood时,我会得到“Shark Fin”。

请帮忙。刚刚开始使用CURL,我并不熟悉CURL

非常感谢=)

4 个答案:

答案 0 :(得分:0)

这不是卷曲问题,这是解析XML的问题,这是您的API通过其外观返回的内容。一个简单的解决方案是使用PHP提供的标准XML解析器之一:

  1. SimpleXML
  2. Dom Parser
  3. PHP提供更多(请参阅手册中的this page),但这两个就足够了。简单的xml解析器就是这么说的。一个简单的解析器。它适用于基本的东西,但是当XML使用命名空间和其他复杂的&#34;时,它将不太理想。东西被喂入它。 DOM解析器基本上可以处理你想要的一切。

    在您的特定情况下,curl_exec将返回此我认为的XML。如果是这种情况,你可以沿着这些方向做点什么:

    // all curl stuff here
    $xmlString = curl_exec($ch);
    $XmlElement = new SimpleXMLElement($xmlString);
    $chineseFoods = $XmlElement->chinese;
    

    您可以直接致电$XmlElement->chinese,因为食物将被解释为XML的根节点&#34;文档&#34;

答案 1 :(得分:0)

从未使用DOMDocument我无法评论如何使用或实际上有多容易,但正如@hoppa所提到的,你可以使用围绕$food=array(); $data=" <foods> <chinese foodtype='soup'>Shark Fin</chinese> <japanese foodtype='fish'>Sushi</japanese> <italian foodtype='wheat'>Pasta</italian> <british foodtype='delicious'>fish n chips</british> </foods>"; /* Try to prevent errors from being displayed */ libxml_use_internal_errors( true ); /* Create the reference to the DOMDocument and set some properties */ $dom=new DOMDocument; $dom->validateOnParse=false; $dom->standalone=true; $dom->preserveWhiteSpace=true; $dom->strictErrorChecking=false; $dom->substituteEntities=false; $dom->recover=true; $dom->formatOutput=false; /* Load the XML data */ $dom->loadXML( $data ); $parse_errs=serialize( libxml_get_last_error() ); libxml_clear_errors(); /* Get the root node and then iterate through it's children */ $foods=$dom->getElementsByTagName('foods')->item(0); foreach( $foods->childNodes as $i => $node ) { if( $node->nodeType==XML_ELEMENT_NODE ){ /* Elements can have attributes, use this methodology to find and get attributes */ $foodtype=$node->hasAttribute('foodtype') ? $node->getAttribute('foodtype') : ''; /* Do whatever you want with the tag or data etc */ echo $node->tagName.' '.$node->nodeValue.' '.$foodtype.BR; /* You could store in an array for later use for example */ $food[ $node->tagName ]=(object)array( 'type'=>$foodtype, 'value'=>$node->nodeValue ); } } $dom=null; /* Later on.... */ $type='chinese'; echo 'From the array: '.$food[ $type ]->type.' '.$food[ $type ]->value; 构建的内置Dom Parsing函数

/**
 * @array hookparams Hookparams array from both of function calls
 */
$hookparams = []; // initalized empty values

function hook_FunctionOne()
{
    //do something, than save result in hookparams array
    $hookparams['key'] = "Foo"; // return? But I can't call FunctionOne once more, and assign return value to temp variable
}

function hook_FunctionTwo(array $hookparams)
{
    //do something with returned hookparams array form function, than save result in hookparams array again 
    $hookparams['key'] .= "Bar"; // Result is "FooBar";
}

// Both functions are called here

run_hook("HookPoint1", "hook_FunctionOne");
run_hook("HookPoint2", "hook_FunctionTwo");

答案 2 :(得分:0)

在DOM中,您可以使用Xpath来获取特定值和节点:

$xml = <<<'XML'
<foods>
     <chinese foodtype='soup'>Shark Fin</chinese>
     <japanese foodtype='fish'>Sushi</japanese>
     <italian foodtype='wheat'>Pasta</italian>
     <british foodtype='delicious'>fish n chips</british>
</foods>
XML;

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

var_dump(
  // the text content of an element node
  $xpath->evaluate('string(/foods/chinese)'),
  // the value of an attribute node
  $xpath->evaluate('string(/foods/chinese/@foodtype)')
);

输出:

string(9) "Shark Fin"
string(4) "soup"

如果结果没有转换为标量(字符串,数字,布尔值),它将始终是一个节点列表,您可以使用foreach迭代:

foreach ($xpath->evaluate('/foods/*[@foodtype = "fish"]') as $food) {
  var_dump(
    [
      'name' => $food->textContent,
      'group' => $food->localName,
      'type' => $food->getAttribute('foodtype')
    ]
  );
}

输出:

array(3) {
  ["name"]=>
  string(5) "Sushi"
  ["group"]=>
  string(8) "japanese"
  ["type"]=>
  string(4) "fish"
}

返回的对象是DOMNode实例,实际的类取决于节点类型。

答案 3 :(得分:-1)

CURL是用于执行HTTP请求/响应的机制。 根据上述描述,CURL请求以XML格式返回响应。

请尝试执行以下代码段来解析XML文档。

<?php 
/** 
 * xml2array() will convert the given XML text to an array in the XML structure. 
 * Link: http://www.bin-co.com/php/scripts/xml2array/ 
 * Arguments : $contents - The XML text 
 *                $get_attributes - 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value.
 *                $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance.
 * Return: The parsed XML in an array form. Use print_r() to see the resulting array structure. 
 * Examples: $array =  xml2array(file_get_contents('feed.xml')); 
 *              $array =  xml2array(file_get_contents('feed.xml', 1, 'attribute')); 
 */ 
function xml2array($contents, $get_attributes=1, $priority = 'tag') { 
    if(!$contents) return array(); 

    if(!function_exists('xml_parser_create')) { 
        //print "'xml_parser_create()' function not found!"; 
        return array(); 
    } 

    //Get the XML parser of PHP - PHP must have this module for the parser to work 
    $parser = xml_parser_create(''); 
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); # http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss 
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 
    xml_parse_into_struct($parser, trim($contents), $xml_values); 
    xml_parser_free($parser); 

    if(!$xml_values) return;//Hmm... 

    //Initializations 
    $xml_array = array(); 
    $parents = array(); 
    $opened_tags = array(); 
    $arr = array(); 

    $current = &$xml_array; //Refference 

    //Go through the tags. 
    $repeated_tag_index = array();//Multiple tags with same name will be turned into an array 
    foreach($xml_values as $data) { 
        unset($attributes,$value);//Remove existing values, or there will be trouble 

        //This command will extract these variables into the foreach scope 
        // tag(string), type(string), level(int), attributes(array). 
        extract($data);//We could use the array by itself, but this cooler. 

        $result = array(); 
        $attributes_data = array(); 

        if(isset($value)) { 
            if($priority == 'tag') $result = $value; 
            else $result['value'] = $value; //Put the value in a assoc array if we are in the 'Attribute' mode
        } 

        //Set the attributes too. 
        if(isset($attributes) and $get_attributes) { 
            foreach($attributes as $attr => $val) { 
                if($priority == 'tag') $attributes_data[$attr] = $val; 
                else $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr' 
            } 
        } 

        //See tag status and do the needed. 
        if($type == "open") {//The starting of the tag '<tag>' 
            $parent[$level-1] = &$current; 
            if(!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag 
                $current[$tag] = $result; 
                if($attributes_data) $current[$tag. '_attr'] = $attributes_data; 
                $repeated_tag_index[$tag.'_'.$level] = 1; 

                $current = &$current[$tag]; 

            } else { //There was another element with the same tag name 

                if(isset($current[$tag][0])) {//If there is a 0th element it is already an array 
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; 
                    $repeated_tag_index[$tag.'_'.$level]++; 
                } else {//This sectio$data = cn will make the value an array if multiple tags with the same name appear together
                    $current[$tag] = array($current[$tag],$result);//This will combine the existing item and the new item together to make an array
                    $repeated_tag_index[$tag.'_'.$level] = 2; 

                    if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well
                        $current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                        unset($current[$tag.'_attr']); 
                    } 

                } 
                $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1; 
                $current = &$current[$tag][$last_item_index]; 
            } 

        } elseif($type == "complete") { //Tags that ends in 1 line '<tag />' 
            //See if the key is already taken. 
            if(!isset($current[$tag])) { //New Key 
                $current[$tag] = $result; 
                $repeated_tag_index[$tag.'_'.$level] = 1; 
                if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;

            } else { //If taken, put all things inside a list(array) 
                if(isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array... 

                    // ...push the new element into that array. 
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result; 

                    if($priority == 'tag' and $get_attributes and $attributes_data) { 
                        $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; 
                    } 
                    $repeated_tag_index[$tag.'_'.$level]++; 

                } else { //If it is not an array... 
                    $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
                    $repeated_tag_index[$tag.'_'.$level] = 1; 
                    if($priority == 'tag' and $get_attributes) { 
                        if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well

                            $current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                            unset($current[$tag.'_attr']); 
                        } 

                        if($attributes_data) { 
                            $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data; 
                        } 
                    } 
                    $repeated_tag_index[$tag.'_'.$level]++; //0 and 1 index is already taken 
                } 
            } 

        } elseif($type == 'close') { //End of tag '</tag>' 
            $current = &$parent[$level-1]; 
        } 
    } 

    return($xml_array); 
}  
    $response_array=xml2array($response);

可以从响应数组变量中轻松检索卷曲响应的信息。