如何使用变量来处理 PHP 中的复杂关联数组


How to use a variable to address complex associative arrays in PHP

假设我有以下多维数组:

$fruits['apple']['name'] = 'macintosh';

有没有办法在单个变量中引用整个密钥路径?

我想以某种方式执行以下操作:

$path = "['apple']['name']";
echo $fruits[$path];
//output would be "macintosh"

有没有办法在单个变量中引用整个键路径?

1)以这样的方式:$fruits[$variable],答案是否定的,没有

当然,有几种方法可以将单个$variable分成两个或多个,然后分别使用其部分($fruits[$part1][$part2]

这是一个通用解决方案:

function get_path($array, $path)
{
    $value = $array;
    $parts = explode("']['", trim($path, "[']"));
    foreach($parts as $key)
    {
        $value = $value[$key];
    }
    return $value;
}
$fruits['apple']['name'] = 'macintosh';
$path = "['apple']['name']";
echo get_path($fruits, $path);
// output = 'macintosh'

2)正如还指出的,您可以使用"eval",不建议这样做:

$fruits['apple']['name'] = 'macintosh';
$path = "['apple']['name']";
eval('echo $fruits' . $path . ';');
// output = 'macintosh'

3)最后,如果你想使用引用变量访问数组的元素,那么只需:

$fruits['apple']['name'] = 'macintosh';
$path &= $fruits['apple']['name'];
echo $path;  // output = 'macintosh'
$path = 'MSX';
echo $fruits['apple']['name'];  // output = 'MSX'

显然有一种可怕的、从未使用过的方法:eval()

但是如果你真的想做这样的事情,我更喜欢这样的方法:

function &array_value_by_address (&$array, $address, $addressSeparator = '/') {
  $parts = explode($addressSeparator, $address);
  $thisLevel = array_shift($parts);
  if (isset($array[$thisLevel])) {
    if ($parts) {
      $ref = &array_value_by_address($array[$thisLevel], implode($addressSeparator, $parts));
      return $ref;
    } else {
      return $array[$thisLevel];
    }
  }
}

由于函数声明中的引用,还可以捕获变量中的返回值并使用它来修改源数组。这是可选的 - 如果在调用时省略&前缀,则捕获的值将只是一个 copu,而不是引用。

但需要注意的是 - 如果数组中的"地址"不存在,函数将返回NULL,但无法区分这种情况和数组中存储的NULL值。

看到它工作

J Brun 的 #3 答案是您最好的选择,但是,他的答案不正确,因为他已经演示了按位 AND 运算符 (&=) 而不是引用赋值。这是更正后的代码:

$fruits['apple'] = array( 'name' => 'macintosh' );
$path = &$fruits['apple']['name'];
echo $path; // outputs 'macintosh';

引用可能是你需要的:

$path = &$fruits['apple']['name'];

现在每次访问$path时,都会使用(或更改等)$fruits['apple']['name']的值。

你想做的事情不是直接可能的 - 如果变量是链接的,那将是模棱两可的。

您将需要编写一个访问器函数,例如

define('SEPARATOR','|');
function getElement($array,$path) {
  $path=explode(SEPARATOR,$path);
  $out=&$array;
  foreach ($path as $step) {
    if (!isset($out[$step])) return null;
    $out=$out[$step];
  }
  return $out;
}
$path="apple|name";
echo getElement($fruits,$path);