2015-04-23 87 views
0

我尝试选择由json_decode()构建的数组的数据。原则上它是一个未知维度的多阵列。php在未知深度的多维数组中搜索

首先,我想递归搜索此数组中的值。作为下一步,我想获得一些其他的高维值。所以这里有一个例子:

我搜索:"2345"

.... 
$json[3][6]['journal']['headline']="news" 
$json[3][6]['journal']['article']=2345 
.... 
$json[8]['journal']['headline']="weather" 
$json[8]['journal']['article']=2345 
.... 

我想要得到的元素headline的值之后(返回“新闻”和“天气”)

它可能是元素2345可以发现在不同的尺寸!

回答

0

有人也许可以做到这一点与RecursiveIteratorIterator对象,但我个人有一个很难用迭代器对象,所以这里是一个相当强大的系统:

<?php 
// This will traverse an array and find the 
// value while storing the base key  
class RecurseLocator 
    { 
     public static $saved = array(); 
     public static $find; 
     public static $trigger; 
     public static function Initialize($find = false) 
      { 
       self::$find = $find; 
      } 

     public static function Recursive(array $array) 
      { 
       foreach($array as $key => $value) { 

         if(!isset(self::$trigger) || (isset(self::$trigger) && empty(self::$trigger))) { 
           if(is_numeric($key)) 
            self::$trigger = $key; 
          } 

         if(!is_array($value)) { 
           if($value == self::$find) { 
             self::$saved[self::$trigger] = $value; 
            } 
          } 

         if(is_array($value)) { 

           $value = self::Recursive($value); 
           if(!is_numeric($key)) 
            self::$trigger = ""; 
          } 


         $return[$key] = $value; 
        } 

       return $return; 
      } 
    } 

// This class will traverse an array searching 
// for a specific key or keys 
class RecurseSearch 
    { 
     public $data; 
     public $compare; 

     public function Find($array = '',$find,$recursive = true) 
      { 
       $find = (is_array($find))? implode("|",$find):$find; 
       if(is_array($array)) { 

         foreach($array as $key => $value) { 

         if(preg_match("/$find/",$key)) 
          $this->compare[$key] = $value; 

           if($recursive == true) { 
             if(!is_array($value)) { 
               if(preg_match("/$find/",$key)) { 
                 $this->data[$key][] = $value; 
                } 

               $array[$key] = $value; 
              } 
             else { 
               if(preg_match("/$find/",$key)) 
                $this->data[$key][] = $this->Find($value,$find); 

               $array[$key] = $this->Find($value,$find); 
              } 
            } 
           else { 
             if(preg_match("/$find/",$key)) 
              $this->data[$key] = $value; 
            } 
          } 

         $this->data = (isset($this->data))? $this->data:false; 

         return $this; 
        } 
      } 
    } 

// This function just wraps the RecurseSearch class 
function get_key_value($array = array(), $find = array(),$recursive = true) 
    { 
     $finder = new RecurseSearch(); 
     return $finder->Find($array,$find,$recursive); 
    } 

用法:

$json[3][6]['journal']['headline'] = "news"; 
    $json[3][6]['journal']['article'] = 2345; 
    $json[8]['journal']['headline']  = "weather"; 
    $json[8]['journal']['article']  = 2345; 
    $json[4][1]['journal']['headline'] = "news"; 
    $json[4][1]['journal']['article'] = 22245; 
    $json[5]['journal']['headline']  = "weather"; 
    $json[5]['journal']['article']  = 233345; 

    // Set the search criteria 
    RecurseLocator::Initialize(2345); 
    // Traverse the array looking for value 
    $arr = RecurseLocator::Recursive($json); 
    // If found, will be stored here 
    $iso = RecurseLocator::$saved; 

    /* $iso looks like: 
    Array 
    (
     [3] => 2345 
     [8] => 2345 
    ) 
    */ 

    // Loop through the $iso array 
    foreach($iso as $key => $value) { 
      // Save to new array your search results 
      $new[] = get_key_value($json[$key],array("headline","article"),true); 
     } 

    /* $new looks like: 
Array 
(
    [0] => RecurseSearch Object 
     (
      [data] => Array 
       (
        [headline] => Array 
         (
          [0] => news 
         ) 

        [article] => Array 
         (
          [0] => 2345 
         ) 
       ) 

      [compare] => Array 
       (
        [headline] => news 
        [article] => 2345 
       ) 
     ) 

    [1] => RecurseSearch Object 
     (
      [data] => Array 
       (
        [headline] => Array 
         (
          [0] => weather 
         ) 

        [article] => Array 
         (
          [0] => 2345 
         ) 
       ) 

      [compare] => Array 
       (
        [headline] => weather 
        [article] => 2345 
       ) 
     ) 
) 
    */ 
?> 

正如一个侧面说明,上面的类存储多个发现[data],然后将它们存储在[compare],但[compare]将overwr如果在一个数组中找到多个相同的键,那么它自己会自动迭代,因为[data]只会保持添加值。

0

只是为编译未知数组创建一个函数。试试这个

$json[1][6]['journal']['headline']="news"; 
$json[1][6]['journal']['article']=2345; 
$json[3][6]['journal']['headline']="HOT"; 
$json[3][6]['journal']['article']=2345; 
$json[8]['journal']['headline']="weather"; 
$json[8]['journal']['article']=2345; 
$json[10]['journal']['headline']="weather"; 
$json[10]['journal']['article']=2345; 

$GLOBALS['list_scan'] = array(); 
$result = array(); 

foreach ($json as $key => $value) 
{ 
    if (is_array($value)) { 
     _compile_scan($key, $value); 
    } 
} 

echo "<pre>"; 
print_r($GLOBALS['list_scan']); 
echo "</pre>"; 

$search = "2345"; 
$keyword = "article"; 
$keyFinder = "headline"; 

foreach ($GLOBALS['list_scan'] as $key => $value) 
{ 
    if ($value == $search) 
    { 
     $addr = substr($key, 0, -(strlen($keyword))).$keyFinder; 
     if (!empty($GLOBALS['list_scan'][$addr])) 
     { 
      $result[] = $GLOBALS['list_scan'][$addr]; 
     } 
    } 
} 
echo "<pre>"; 
print_r($result); 
echo "</pre>"; 


function _compile_scan($index, $value) 
{ 
    $pointer =& $GLOBALS['list_scan']; 

    foreach ($value as $key => $val) 
    { 
     $temp = ''; 
     $temp = $index.'|'.$key; 
     if (is_array($val)) 
     { 
      // $pointer[$temp] = $val; 
      _compile_scan($temp, $val); 
     } 
     else $pointer[$temp] = $val; 
    } 
} 

输出:

Array 
(
    [1|6|journal|headline] => news 
    [1|6|journal|article] => 2345 
    [3|6|journal|headline] => HOT 
    [3|6|journal|article] => 2345 
    [8|journal|headline] => weather 
    [8|journal|article] => 2345 
    [9|journal|headline] => Others 
    [9|journal|article] => 234521 
) 
Array 
(
    [0] => news 
    [1] => HOT 
    [2] => weather 
)