PHP函数可以从数组键返回一个动态深度级别的值

时间:2014-03-19 14:06:27

标签: php arrays dynamic

使用PHP,我想编写一个函数来完成这个伪代码所显示的内容:

function return_value($input_string='array:subArray:arrayKey') 
{
    $segments = explode(':',$input_string);
    $array_depth = count(segments) - 1;

    //Now the bit I'm not sure about
    //I need to dynamically generate X number of square brackets to get the value
    //So that I'm left with the below:

    return $array[$subArray][$arrayKey];
}

以上可能吗?我非常欣赏如何实现它的一些指针。

3 个答案:

答案 0 :(得分:2)

你可以使用递归函数(或它的迭代等价,因为它是尾递归):

function return_value($array, $input_string) {
    $segments = explode(':',$input_string);

    // Can we go next step?
    if (!array_key_exists($segments[0], $array)) {
        return false; // cannot exist
    }

    // Yes, do so.
    $nextlevel = $array[$segments[0]];
    if (!is_array($nextlevel)) {
        if (1 == count($segments)) {
            // Found!
            return $nextlevel;
        }
        // We can return $nextlevel, which is an array. Or an error.
        return false; 
    }
    array_shift($segments);
    $nextsegments = implode(':', $segments);

    // We can also use tail recursion here, enclosing the whole kit and kaboodle
    // into a loop until $segments is empty.
    return return_value($nextlevel, $nextsegments);
}

传递一个对象

假设我们希望这是一个API并且只传递一个字符串(请记住,HTTP在这方面有一些方法限制,你可能需要POST字符串而不是GET)。

该字符串需要包含两者数组数据“key”位置。我们最好首先发送密钥然后发送数组:

function decodeJSONblob($input) {
    // Step 1: extract the key address. We do this is a dirty way,
    // exploiting the fact that a serialized array starts with
    // a:<NUMBEROFITEMS>:{ and there will be no "{" in the key address.
    $n = strpos($input, ':{');
    $items = explode(':', substr($input, 0, $n));
    // The last two items of $items will be "a" and "NUMBEROFITEMS"
    $ni = array_pop($items);
    if ("a" != ($a = array_pop($items))) {
        die("Something strange at offset $n, expecting 'a', found {$a}");
    }
    $array = unserialize("a:{$ni}:".substr($input, $n+1));

    while (!empty($items)) {
        $key = array_shift($items);
        if (!array_key_exists($key, $array)) {
            // there is not this item in the array.
        }
        if (!is_array($array[$key])) {
            // Error.
        }
        $array = $array[$key];
     }
     return $array;
}

$arr = array(
    0 => array(
        'hello' => array( 
             'joe','jack',
             array('jill')
         )));

print decodeJSONblob("0:hello:1:" . serialize($arr));
print decodeJSONblob("0:hello:2:0" . serialize($arr));

返回

jack
jill

在询问0:hello:2:时会得到一个数组{ 0: 'jill' }

答案 1 :(得分:0)

您可以使用recursionarray_key_exists向下走到所述密钥的级别。

function get_array_element($key, $array) 
{
  if(stripos(($key,':') !== FALSE) {
    $currentKey    = substr($key,0,stripos($key,':'));
    $remainingKeys = substr($key,stripos($key,':')+1);
    if(array_key_exists($currentKey,$array)) {
      return ($remainingKeys,$array[$currentKey]);
    }
    else {
      // handle error
      return null;
    }
  }
  elseif(array_key_exists($key,$array)) {
    return $array[$key];
  }
  else {
    //handle error
    return null;
  }
}

答案 2 :(得分:0)

使用如下的递归函数或使用对数组键的引用的循环

<?php

function lookup($array,$lookup){
        if(!is_array($lookup)){
                $lookup=explode(":",$lookup);
        }
        $key = array_shift($lookup);
        if(!isset($array[$key])){
                //throw exception if key is not found so false values can also be looked up
                throw new Exception("Key does not exist");
        }else{
                $val = $array[$key];
                if(count($lookup)){
                        return lookup($val,$lookup);
                }
                return $val;
        }
}

$config = array(
        'db'=>array(
                'host'=>'localhost',
                'user'=>'user',
                'pass'=>'pass'
        ),
        'data'=>array(
                'test1'=>'test1',
                'test2'=>array(
                        'nested'=>'foo'
                )
        )

);


echo "Host: ".lookup($config,'db:host')."\n";
echo "User: ".lookup($config,'db:user')."\n";
echo "More levels: ".lookup($config,'data:test2:nested')."\n";

输出:

Host: localhost
User: user
More levels: foo