如何将基于多层循环的PHP JSON标签值收集函数改造为递归实现
用递归替代多层循环收集嵌套JSON中的label和value属性
你遇到的这个问题太典型了——固定层数的foreach循环只能适配特定深度的嵌套结构,一旦JSON里的descends层级变深,就得不断加循环,维护起来特别麻烦。递归确实是解决这类无限嵌套场景的完美方案,先帮你把原来的函数改成递归实现,再给你拆解下逻辑:
递归实现代码
public function collectValues($element) { $finalValues = []; // 先收集当前节点的label和value(如果存在) if (isset($element['label']) && isset($element['value'])) { $finalValues[] = [ 'label' => $element['label'], 'value' => $element['value'] ]; } // 如果当前节点有descends数组,递归处理每个子节点 if (isset($element['descends']) && is_array($element['descends'])) { foreach ($element['descends'] as $childNode) { // 递归调用并合并子节点的收集结果 $finalValues = array_merge($finalValues, $this->collectValues($childNode)); } } return $finalValues; }
使用方式
注意你的JSON解析后是关联数组(不是对象),调用时直接传入顶层的block节点即可:
// 假设$arr是你json_decode后的关联数组(记得加true参数) $result = $this->collectValues($arr['block']);
为什么这个递归方案更好?
- 无限层级兼容:不管
descends嵌套多少层,递归都会自动遍历到最底层的节点,不用再手动加foreach循环 - 代码更简洁易维护:逻辑一目了然,相比多层嵌套的循环,后期修改成本极低
- 鲁棒性更强:只要结构符合「可能有label/value,可能有descends子数组」的规则,就能正确处理
补充说明
- 修正了你原函数里的拼写错误:
lable改成了正确的label - 如果你需要和原函数的结果顺序完全一致(先子节点后父节点),只需要把「收集当前节点」的代码放到「递归处理子节点」之后即可
内容的提问来源于stack exchange,提问作者mnlixk
相关产品推荐
相关产品推荐

