2016-02-26 74 views
1

好吧,所以我需要用PHP動態挖掘出JSON結構,我甚至不知道它是否可能。用PHP動態挖掘JSON

所以,讓我們說,我的JSON存儲廣告變量$data

$data = { 
    'actions':{ 
    'bla': 'value_actionBla', 
    'blo': 'value_actionBlo', 
    } 
} 

所以,要訪問的value_actionsBla的價值,我只是做$data['actions']['bla']。夠簡單。

我的JSON是動態生成的,而接下來的時間,它是這樣的:

$data = { 
    'actions':{ 
    'bla': 'value_actionBla', 
    'blo': 'value_actionBlo', 
    'bli':{ 
     'new': 'value_new' 
    } 
    } 
} 

再次,拿到new_value,我做的:$data['actions']['bli']['new']

我想你會看到這個問題。

如果我需要兩個級別,然後我需要寫$data['first_level']['second_level'],有三個,這將是$data['first_level']['second_level']['third_level']等等...

有什麼辦法來動態地進行這樣的行動? (給我認識的鍵)

EDIT_0:這裏是我如何做到這一點到目前爲止的例子(在沒有動態的方式,用2個水平

// For example, assert that 'value_actionsBla' == $data['actions']['bla'] 
foreach($data as $expected => $value) { 
    $this->assertEquals($expected, $data[$value[0]][$value[1]]); 
} 

EDIT_1

我已經做了遞歸函數來做到這一點的基礎上,@Matei米哈伊的解決方案:

private function _isValueWhereItSupposedToBe($supposedPlace, $value, $data){ 
     foreach ($supposedPlace as $index => $item) { 
      if(($data = $data[$item]) == $value) 
       return true; 
      if(is_array($item)) 
       $this->_isValueWhereItSupposedToBe($item, $value, $data); 
     } 
     return false; 
} 

public function testValue(){ 
     $searched = 'Found'; 
     $data = array(
      'actions' => array(
       'abort' => '/abort', 
       'next' => '/next' 
      ), 
      'form' => array(
       'title' => 'Found' 
      ) 
     ); 
     $this->assertTrue($this->_isValueWhereItSupposedToBe(array('form', 'title'), $searched, $data)); 
} 
+0

你是否事先知道你正在尋找的價值?就像'action'是一個命名動作的數組,什麼時候是一個字符串或一個對象的值? – Halcyon

+0

在這兩個例子中,我們正在尋找不同的密鑰。你怎麼知道你在找什麼節點?您可以使用遞歸函數來遍歷所有節點,但沒有常量名稱來搜索它將無法工作。 –

+0

我事先知道所有事情,因爲它是一個PHPUnit測試套件。對於特定的請求,我知道我應該收到特定的JSON。 – Mornor

回答

2

可以使用遞歸函數:

function array_search_by_key_recursive($needle, $haystack) 
{ 
    foreach ($haystack as $key => $value) { 
     if ($key === $needle) { 
      return $value; 
     } 
     if (is_array($value) && ($result = array_search_by_key_recursive($needle, $value)) !== false) { 
      return $result; 
     } 
    } 

    return false; 
} 

$arr = ['test' => 'test', 'test1' => ['test2' => 'test2']]; 

var_dump(array_search_by_key_recursive('test2', $arr)); 

結果是string(5) "test2"

+1

我根據你的解決方案做了一些改進:) – Mornor

1

你可以使用這樣的功能,以遞歸遍歷下一個數組(因爲你知道你想要的值,所有的按鍵訪問):

function array_get_nested_value($data, array $keys) { 
    if (empty($keys)) { 
     return $data; 
    } 
    $current = array_shift($keys); 
    if (!is_array($data) || !isset($data[$current])) { 
     // key does not exist or $data does not contain an array 
     // you could also throw an exception here 
     return null; 
    } 
    return array_get_nested_value($data[$current], $keys); 
} 

使用這樣的:

$array = [ 
    'test1' => [ 
     'foo' => [ 
      'hello' => 123 
     ] 
    ], 
    'test2' => 'bar' 
]; 
array_get_nested_value($array, ['test1', 'foo', 'hello']); // will return 123