PHP遍历stdClass动态添加属性引发内存耗尽的原因咨询
为什么你的PHP代码会触发内存耗尽错误?
这个问题的核心原因是你在遍历stdClass对象的过程中动态添加新属性,导致foreach进入了无限循环,不断创建新属性直到耗尽PHP的内存限制。
具体执行过程拆解
让我们一步步拆解代码的运行逻辑:
- 初始对象只有两个属性:
a和b。 - 第一次
foreach迭代,$field为a,你给对象新增了new_a属性。 - 第二次迭代,
$field为b,又新增了new_b属性。 - 这里关键的点来了:
foreach遍历对象时,会动态读取对象的当前属性列表——此时对象已经有a、b、new_a、new_b四个属性了。 - 于是第三次迭代,
$field变成new_a,你又添加了new_new_a;第四次迭代$field是new_b,添加new_new_b…… - 这个过程会无限重复:每次迭代都会新增一个属性,而新增的属性又会被下一轮
foreach遍历到,再生成新的属性,直到PHP的内存被完全占满,触发内存耗尽错误。
验证循环的小测试
你可以在循环里加一行输出,直观看到这个无限循环的过程:
<?php $obj = new stdClass(); $obj->a = 'A'; $obj->b = 'B'; foreach($obj as $field=>$value) { echo "当前遍历的属性:$field\n"; $obj->{'new_'.$field} = $value; }
运行后你会看到输出不断打印a、b、new_a、new_b、new_new_a、new_new_b……根本停不下来。
如何避免这个问题?
解决思路是先获取对象初始的属性列表,再基于这个固定的列表进行遍历,这样就不会因为新增属性导致循环无限进行。比如:
<?php $obj = new stdClass(); $obj->a = 'A'; $obj->b = 'B'; // 先获取初始属性的数组副本 $originalFields = get_object_vars($obj); foreach($originalFields as $field=>$value) { $obj->{'new_'.$field} = $value; }
这样遍历的是一开始的['a'=>'A', 'b'=>'B']数组,只会循环两次,不会触发无限循环。
内容的提问来源于stack exchange,提问作者C. R.
相关产品推荐
相关产品推荐

