迭代多维PHP对象按引用修改值时部分数组字符串未变更问题
问题成因
- PHP 中数组属于值类型,默认传参规则为传值而非引用:你当前编写的函数未将参数声明为引用类型,递归传入数组时,函数内部操作的是数组的副本,所有修改都不会同步到原数组中
- 对象在 PHP 中默认按引用传递,所以对象层级的字符串修改可以正常生效,只有数组嵌套内的修改会丢失,刚好对应你遇到的异常表现
可行解决方案
直接将函数参数声明为引用传递即可修复问题,修改后的完整代码如下:
recursive_object_string_changer($object); // 参数前加&开启引用传递,数组/对象传入时都会操作原数据而非副本 function recursive_object_string_changer(&$object) { if($object == null) { return; } foreach ($object as &$attribute) { if (is_string($attribute)) { $attribute = $attribute."!"; } else if (is_array($attribute) || is_object($attribute)) { recursive_object_string_changer($attribute); } } unset($attribute); // 保留该语句避免循环结束后残留引用,干扰后续逻辑 }
可选优化说明
如果需要处理自定义类的非公开属性(private/protected 修饰的属性),原遍历逻辑只能读取到公开属性,可借助ReflectionClass实现全属性遍历,对应逻辑示例如下:
function recursive_object_string_changer(&$object) { if($object == null) { return; } // 单独处理对象类型,用反射读取所有属性 if (is_object($object)) { $reflection = new ReflectionClass($object); foreach ($reflection->getProperties() as $prop) { $prop->setAccessible(true); $value = $prop->getValue($object); if (is_string($value)) { $prop->setValue($object, $value . '!'); } else if (is_array($value) || is_object($value)) { recursive_object_string_changer($value); $prop->setValue($object, $value); } } } else if (is_array($object)) { // 数组沿用原有遍历逻辑 foreach ($object as &$attribute) { if (is_string($attribute)) { $attribute = $attribute."!"; } else if (is_array($attribute) || is_object($attribute)) { recursive_object_string_changer($attribute); } } unset($attribute); } }
内容的提问来源于stack exchange,提问作者testtesttesteettesttesttesttes
相关产品推荐
相关产品推荐

