PHP如何通过引用删除嵌套stdClass属性(不将属性设为null)
问题根因
你现有写法的失效原因很明确:unset($dataReference)只会销毁你创建的这个引用变量本身,仅断开引用变量和原对象属性的绑定关系,完全不会影响到原对象上的属性。
解决方案
不需要遍历到最后一层属性做引用,只要循环走到目标属性的父级节点就停止,直接对父级对象执行unset操作即可,完全不需要将属性赋值为null,是真正的属性删除。
修改后的可运行代码如下:
<?php $data = new stdClass(); $data->foo = new stdClass(); $data->foo->bar = 'value'; $pathToRemove = 'foo.bar'; $fields = explode('.', $pathToRemove); // 提取最后一层待删除的属性名 $targetField = array_pop($fields); $parentNode = $data; // 遍历到目标属性的父级节点 foreach ($fields as $field) { $parentNode = $parentNode->$field; } // 直接删除父级节点上的目标属性 unset($parentNode->$targetField); var_dump($data);
运行后输出结果可以看到,$data->foo的bar属性已经被完全删除,符合预期。
如果需要兼容路径不存在的场景,避免报错,可以加一层边界判断:
<?php $data = new stdClass(); $data->foo = new stdClass(); $data->foo->bar = 'value'; $pathToRemove = 'foo.bar'; $fields = explode('.', $pathToRemove); if (count($fields) === 0) { throw new \InvalidArgumentException('删除路径不能为空'); } // 提取最后一层待删除的属性名 $targetField = array_pop($fields); $parentNode = $data; // 遍历到目标属性的父级节点,同时做合法性校验 foreach ($fields as $field) { if (!isset($parentNode->$field) || !$parentNode->$field instanceof \stdClass) { throw new \RuntimeException('指定的删除路径不存在'); } $parentNode = $parentNode->$field; } // 存在目标属性才执行删除 if (isset($parentNode->$targetField)) { unset($parentNode->$targetField); } var_dump($data);
内容的提问来源于stack exchange,提问作者Estern
相关产品推荐
相关产品推荐

