2016-02-26 48 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