2

我正在尝试通过描述数组路径的字符串(如 )从多维数组中检索项目first.second.third

我选择了这里显示的方法(也可以在 ideone 上找到):

<?php
    // The path into the array
    $GET_VARIABLE = "a.b.c";
    // Some example data
    $GLOBALS["a"]= array("b"=>array("c"=>"foo"));

    // Construct an accessor into the array
    $variablePath = explode( ".", $GET_VARIABLE );
    $accessor = implode( "' ][ '", $variablePath );
    $variable = "\$GLOBALS[ '". $accessor . "' ]";

    // Print the value for debugging purposes (this works fine)
    echo $GLOBALS["a"]["b"]["c"] . "\n";
    // Try to evaluate the accessor (this will fail)
    echo $$variable;
?>

当我运行脚本时,它将打印两行:

foo
PHP Notice:  Undefined variable: $GLOBALS[ 'a' ][ 'b' ][ 'c' ] in ...

那么,为什么这不能正确评估呢?

4

4 回答 4

5

我认为这个$$符号只接受一个变量名(即变量名)。您实际上是在尝试读取一个名为“ $GLOBALS[ 'a' ][ 'b' ][ 'c' ]”的变量,该变量不存在。

作为替代方案($GET_VARIABLE似乎是您的输入字符串),您可以试试这个:

$path = explode('.', $GET_VARIABLE);
echo $GLOBALS[$path[0]][$path[1]][path[2]];

将其包裹在合适的循环中以使其更具动态性;这似乎是微不足道的。

于 2013-07-09T14:55:33.827 回答
2

看起来 PHP 将整个字符串视为变量名,而不是数组。

您可以尝试使用以下方法,因为它也可能更简单。

<?php
    // The path into the array
    $GET_VARIABLE = "a.b.c";
    // Some example data
    $GLOBALS["a"]= array("b"=>array("c"=>"foo"));

    // Construct an accessor into the array
    $variablePath = explode( ".", $GET_VARIABLE );
    //$accessor = implode( "' ][ '", $variablePath );
    //$variable = "\$GLOBALS[ '". $accessor . "' ]";

    // Print the value for debugging purposes (this works fine)
    echo $GLOBALS["a"]["b"]["c"] . "\n";
    // Try to evaluate the accessor (this will fail)
    echo $GLOBALS[$variablePath[0]][$variablePath[1]][$variablePath[2]];
?>
于 2013-07-09T14:56:32.660 回答
1

这是使用辅助函数的另一种解决方案:

function GetValue($path, $scope = false){
    $result = !empty($scope) ? $scope : $GLOBALS;

    // make notation uniform
    $path = preg_replace('/\[([^\]]+)\]/', '.$1', $path); // arrays
    $path = str_replace('->', '.', $path); // object properties

    foreach (explode('.', $path) as $part){
        if (is_array($result) && array_key_exists($part, $result)){
            $result = $result[$part];
        } else if (is_object($result) && property_exists($result, $part)){
            $result = $result->$part;
        } else {
            return false; // erroneous
        }
    }
    return $result;
}

以及示例用法:

// Some example data
$GLOBALS["a"] = array(
  'b' => array(
    'c' => 'foo',
    'd' => 'bar',
   ),
   'e' => (object)array(
     'f' => 'foo',
     'g' => 'bar'
   )
);
$bar = array(
  'a' => $GLOBALS['a']
);

echo $GLOBALS['a']['b']['c'] . "\n"; // original

// $GLOBALS['a']['b']['c']
echo GetValue('a.b.c')       . "\n"; // traditional usage
// $GLOBALS['a']['b']['c']
echo GetValue('a[b][c]')     . "\n"; // different notation
// $bar['a']['b']['c']
echo GetValue('a.b.c', $bar) . "\n"; // changing root object
// $GLOBALS['a']['e']->f
echo GetValue('a[e]->f')     . "\n"; // object notation
于 2013-07-09T15:25:37.697 回答
1

这是我编写的一些代码,用于通过点符号访问 $_SESSION 变量。你应该能够相当容易地翻译它。

<?php
$key = "a.b.c";    
$key_bits = explode(".", $key);

$cursor = $_SESSION;

foreach ($key_bits as $bit)
{
    if (isset($cursor[$bit]))
    {
        $cursor = $cursor[$bit];
    }
    else
    {
        return false;
    }
}

return $cursor;
于 2013-07-09T14:59:45.163 回答