变量是否可以计算为多维PHP数组索引

变量是否可以计算为多维PHP数组索引,php,arrays,Php,Arrays,给定多维数组或字典$array 假设$array['foo']['bar']['baz']='something' 对于我来说,除了通过eval语句之外,还有什么方法可以使用多维索引foo/bar/baz?(用例是动态创建索引,即函数不知道/foo/bar/baz/是什么) 我能想到的唯一方法是: $item = testGetIndex($array, "'foo']['bar']['baz'"); function testGetIndex($array, $index) { eval

给定多维数组或字典
$array

假设
$array['foo']['bar']['baz']='something'

对于我来说,除了通过eval语句之外,还有什么方法可以使用多维索引
foo/bar/baz
?(用例是动态创建索引,即函数不知道/foo/bar/baz/是什么)

我能想到的唯一方法是:

$item = testGetIndex($array, "'foo']['bar']['baz'");

function testGetIndex($array, $index) {
  eval('$item = $array[' . $index . '];');
  return $item;
}

注意: 我应该提到我不想搜索这个数组。这是一个奇怪的用例。我被传递到一个非常大的多维数组中,使用像..这样的结构很难看

$array[foo][bar].[baz]
对数组进行修改。

公然重复使用:

编辑:正如Jack指出的,不需要递归:

function findByKey(array $keys,array $array){
    while(!is_null($key = array_shift($keys))){
        if(!isset($array[$key])) return null;
        $array = $array[$key];
    }
    return $array;
}
$values = findByKey(explode('/','foo/bar/baz'),$yourArray);
公然重复使用:

编辑:正如Jack指出的,不需要递归:

function findByKey(array $keys,array $array){
    while(!is_null($key = array_shift($keys))){
        if(!isset($array[$key])) return null;
        $array = $array[$key];
    }
    return $array;
}
$values = findByKey(explode('/','foo/bar/baz'),$yourArray);

要使用路径修改阵列,请执行以下操作:

function setPath(&$root, $path, $value)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current = $value;
}
$path = 'foo/bar/baz';
$root = array('foo' => array('bar' => array('baz' => 'something')));

setPath($root, $path, '123');
您可以调整函数以仅返回对要更改的元素的引用:

function &getPath(&$root, $path)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current;
}

$x = &getPath($root, $path);

$x = 456; // $root['foo']['bar']['baz'] == 456

要使用路径修改阵列,请执行以下操作:

function setPath(&$root, $path, $value)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current = $value;
}
$path = 'foo/bar/baz';
$root = array('foo' => array('bar' => array('baz' => 'something')));

setPath($root, $path, '123');
您可以调整函数以仅返回对要更改的元素的引用:

function &getPath(&$root, $path)
{
        $paths = explode('/', $path);
        $current = &$root;

        foreach ($paths as $path) {
                if (isset($current[$path])) {
                        $current = &$current[$path];
                } else {
                        return null;
                }
        }

        return $current;
}

$x = &getPath($root, $path);

$x = 456; // $root['foo']['bar']['baz'] == 456

一个简单的循环就可以实现,如:

function get(array $array, $keys) {
  $val = $array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      return null;
    }
    $val = $val[$part];
  }
  return $val;
}

$array['foo']['bar']['baz'] = 'something';
echo get($array, 'foo/bar/baz');

编辑

要进行修改,只需使用引用:

function set(array &$array, $keys, $value) {
  $val = &$array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      $val[$part] = array();
    }
    $val = &$val[$part];
  }
  $val = $value;
}

一个简单的循环就可以实现,比如:

function get(array $array, $keys) {
  $val = $array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      return null;
    }
    $val = $val[$part];
  }
  return $val;
}

$array['foo']['bar']['baz'] = 'something';
echo get($array, 'foo/bar/baz');

编辑

要进行修改,只需使用引用:

function set(array &$array, $keys, $value) {
  $val = &$array;
  foreach (explode('/', $keys) as $part) {
    if (!isset($val[$part])) {
      $val[$part] = array();
    }
    $val = &$val[$part];
  }
  $val = $value;
}

我不确定我是否完全理解您的问题,但听起来您正在寻找使用类似于
array\u search
的数组进行搜索:
eval
的可能重复是将脚本与编译语言分开的原因,对于这样的情况,这是非常好的;只要你知道你在做什么(没有未录制的输入)。手动遍历方法也同样有效,但当你说“进行修改”时,你需要一种参考明智的遍历方法。@mario是的,我很喜欢我的简单易懂的eval策略,但有人警告我不要在任何事情上使用eval。我希望PHP有一个数组函数来为我实现这一点:(我不确定是否完全理解您的问题,但听起来您正在寻找使用类似于
array\u search
的数组进行搜索:
eval
的可能重复是将脚本与编译语言区分开来的原因,并且在这种情况下完全可以;只要您知道自己在做什么(没有未录制的输入)。手动遍历方法也同样有效,但当你说“进行修改”时,你需要一种基于引用的遍历方法。@mario是的,我很喜欢我的简单易懂的eval策略,但有人警告我不要将eval用于任何事情。我希望PHP有一个数组函数来帮我做到这一点:(为什么是递归?这个问题很容易用迭代的方式表达。结果我们都错了,因为OP想要一种对数组进行修改的方法,而不是找到值。@jack:那么,对rescue的引用……与您刚才发布的完全相同,所以我不想麻烦;)为什么是递归?这个问题很容易用迭代的方式表达。结果我们都错了,因为OP想要一种对数组进行修改的方法,而不是找到值。@jack:那么,对rescue的引用……与您刚才发布的完全相同,所以我不想麻烦;)显然,OP需要函数来修改数组,而不仅仅是读取数组。显然,OP需要函数来修改数组,而不仅仅是读取数组。