PHP如何用可变变量动态访问数组键?求助解决方法
问题:PHP通过可变变量动态访问数组(含多级索引)
我有一个存储数据的数组,希望用可变变量实现数组的动态访问,但PHP会把带数组键的完整字符串识别成单个变量名,而非“变量+关联键”的组合。
示例代码
$myArrayWithData = ["info" => 1]; $myvarvarArray = "myArrayWithData['info']"; print_r($$myvarvarArray);
预期输出
1
实际输出
Notice: Undefined variable: myArrayWithData['info']
我不想硬编码索引,因为要开发一个Twig函数,需要通过字符串生成数组索引路径,无法提前预知数组键。
硬编码索引的可行示例:
$myvarvarArray = "myArrayWithData"; print_r($$myvarvarArray["info"]); # 硬编码索引
补充:函数需支持多级索引
原函数代码:
/** * 替代merge方法,向Twig数组中添加值 * * @param $object 要设置新值的数组或对象(需公共访问权限) * @param string $context 值要被设置的完整路径,示例:"children.grandchildren.info" * @param $value 要插入的值 * */ public function enhancedMerge($object, $contexts, $value){ $contexts = explode('.', $contexts); $newObject = $object; $path = ''; foreach($contexts as $key => $context){ $objectWithPath = 'newObject' . $path; $contextIsArray = is_array(${$objectWithPath}) ? true : false; if($contextIsArray){ $path .= "['" . $context . "']"; }else{ $path .= "->" . $context; } } $objectWithPath = $newObject . $path; $$objectWithPath = $value; return $$newObject; }
解决方案
核心问题说明
PHP的可变变量仅能解析单纯的变量名,无法识别变量名后的数组/对象访问语法(比如['key']或->property),所以拼接路径字符串的方式不可行。
方法1:基础动态访问(单级索引)
先通过可变变量拿到数组本身,再动态访问对应键:
$myArrayWithData = ["info" => 1]; $varName = "myArrayWithData"; $key = "info"; // 先获取数组变量,再访问键 print_r($$varName[$key]);
方法2:适配多级索引的改进函数
改用引用指向当前层级的数组/对象,逐层遍历索引路径,直接操作目标节点:
/** * 替代merge方法,向Twig数组中添加值 * * @param $object 要设置新值的数组或对象(需公共访问权限) * @param string $context 值要被设置的完整路径,示例:"children.grandchildren.info" * @param $value 要插入的值 * */ public function enhancedMerge($object, $contexts, $value){ $contexts = explode('.', $contexts); // 用引用指向当前层级的对象/数组,避免拷贝 $current = &$object; foreach($contexts as $index => $context){ // 最后一层级直接赋值 if($index === count($contexts) - 1){ if(is_array($current)){ $current[$context] = $value; }elseif(is_object($current)){ $current->$context = $value; } break; } // 非最后层级,确保当前节点存在并切换层级 if(is_array($current)){ if(!isset($current[$context])){ $current[$context] = []; } $current = &$current[$context]; }elseif(is_object($current)){ if(!isset($current->$context)){ $current->$context = new stdClass(); } $current = &$current->$context; } } return $object; }
内容的提问来源于stack exchange,提问作者Erick Est
相关产品推荐
相关产品推荐

