我正在尝试通过描述数组路径的字符串从多维数组中检索项目(如first.second.third
)。
我选择了这里显示的方法(also available on 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 ...
那么,为什么这不能正确评估?
答案 0 :(得分:5)
我认为$$
表示法只接受变量名称(即变量名称)。您实际上是在尝试读取名为“$GLOBALS[ 'a' ][ 'b' ][ 'c' ]
”的变量,该变量不存在。
作为替代方案($GET_VARIABLE
似乎是您的输入字符串),您可以尝试这样做:
$path = explode('.', $GET_VARIABLE);
echo $GLOBALS[$path[0]][$path[1]][path[2]];
将其包裹在合适的环中,使其更具动感;这似乎是微不足道的。
答案 1 :(得分: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]];
?>
答案 2 :(得分: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;
答案 3 :(得分: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