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


PHP - how to get specific value of curl response

我使用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时,我会得到"鱼翅"。

请帮忙。今天刚开始CURL,我对CURL 不是很熟悉

非常感谢=)

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

  1. SimpleXML
  2. Dom分析器

PHP提供了更多(请参阅手册中的这一页),但这两个就足够了。简单的xml解析器正是它所说的。一个简单的解析器。它可以处理基本的内容,但当使用名称空间和其他"复杂"内容的XML被输入其中时,它就不那么理想了。DOM解析器基本上可以处理您想要的所有内容。

在您的特定情况下,curl_exec将返回这个XML。如果是这样的话,你可以沿着以下路线做一些事情:

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

您可以直接调用$XmlElement->chinese,因为食物将被解释为XML"文档"的根节点

从未使用过SimpleXML,我无法评论如何使用或它有多简单,但正如@hoppa所提到的,您可以使用围绕DOMDocument 构建的内置Dom解析函数

$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中,您可以使用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实例,实际的类取决于节点类型。

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

curl响应的信息可以很容易地从响应数组变量中检索到。