指向数组或嵌套对象的变量

Variable Variables Pointing to Arrays or Nested Objects

提问人:K-2052 提问时间:1/10/2010 最后编辑:johnnyArtK-2052 更新时间:1/14/2020 访问量:4798

问:

是否可以创建指向数组或嵌套对象的变量变量?php 文档特别说你不能指向 SuperGlobals,但不清楚(至少对我来说)这是否适用于一般的数组。

这是我对数组 var var 的尝试。

     // Array Example
     $arrayTest = array('value0', 'value1');
     ${arrayVarTest} = 'arrayTest[1]';
     // This returns the correct 'value1'
     echo $arrayTest[1];
     // This returns null
     echo ${$arrayVarTest};   

这里有一些简单的代码来说明我所说的对象 var var 是什么意思。

     ${OBJVarVar} = 'classObj->obj'; 
     // This should return the values of $classObj->obj but it will return null  
     var_dump(${$OBJVarVar});    

我在这里遗漏了一些明显的东西吗?

php 变量 对象属性

评论

0赞 johnnyArt 1/10/2010
更新了我的答案以包括数组索引问题,我误读了你,并认为你已经控制住了!
0赞 Michał Niedźwiedzki 1/17/2010
如果变量变量是答案,你可能问错了问题。为什么不直接使用按引用分配呢?

答:

0赞 Philippe Gerber 1/10/2010 #1

在 vars 名称中,数组索引为 ,而不是 。括号是 PHP“关键字”。与方法表示法和运算符相同。所以你需要分手。echo $arrayTest[1];$arrayTest1$arrayTest[1]->

// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];

// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;

你想做的听起来更像是评估PHP代码()。但请记住:eval 是邪恶的。;-)eval()

0赞 mauris 1/10/2010 #2

不,你不能那样做。您只能使用变量、对象和函数名称来执行此操作。

例:

 $objvar = 'classObj';
 var_dump(${$OBJVarVar}->var);

替代方案可以通过 eval() 或进行预处理。

$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';

echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');

也就是说,如果您非常确定输入的内容。

通过预处理:

function varvar($str){
  if(strpos($str,'->') !== false){
    $parts = explode('->',$str);
    global ${$parts[0]};
    return $parts[0]->$parts[1];
  }elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
    $parts = explode('[',$str);
    global ${$parts[0]};
    $parts[1] = substr($parts[1],0,strlen($parts[1])-1);
    return ${$parts[0]}[$parts[1]];
  }else{
    return false;
  }
}

$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
3赞 Lukman 1/10/2010 #3

用于通过引用进行分配:= &

 $arrayTest = array('value0', 'value1');
 $arrayVarTest = &$arrayTest[1];

 $arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference

 print $arrayVarTest;

评论

0赞 mauris 1/10/2010
asker 不是在问引用。
0赞 hugsbrugs 5/22/2015
@mauris :也许吧,但是在谷歌搜索时找到这个答案给了我正在寻找的解决方案;)
5赞 johnnyArt 1/10/2010 #4

数组元素方法

  • 从字符串中提取数组名称并将其存储在 中。$arrayName
  • 从字符串中提取数组索引并将其存储在 中。$arrayIndex
  • 正确解析它们,而不是作为一个整体。

代码:

$arrayTest  = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName  = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);

// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];

对象属性方法

  • 通过分隔符 (->) 分解包含要访问的类和属性的字符串。
  • 将这两个变量分配给 和 。$class$property
  • 单独解析它们,而不是作为一个整体来解析它们var_dump()

代码:

$variableObjectProperty = "classObj->obj";
list($class,$property)  = explode("->",$variableObjectProperty);

// This now return the values of $classObj->obj
var_dump(${$class}->{$property});    

它有效!

评论

0赞 K-2052 1/10/2010
谢谢!这正是我想要完成的。效果很好。
0赞 Mostafa Nobaqi 1/14/2020 #5

对于许多嵌套级别,有一种动态方法:

$attrs = ['level1', 'levelt', 'level3',...];
$finalAttr = $myObject;
foreach ($attrs as $attr) {
    $finalAttr = $finalAttr->$attr;
}
return $finalAttr;