PHP递归转换无限层级资源数组为带父级信息的扁平数组
问题描述
需要将支持无限嵌套子级的资源数组转换为扁平结构数组,转换时需保留每个资源的父级关联信息(本场景下父级指子数组直接上层的对应资源)。实际场景中该数组规模更大,每个子节点都可能嵌套无限层级的子数组。
示例输入
$array = array ( 0 => array ( '@id' => 'Authorization', '@sortOrder' => '1', 'resource' => array ( '@id' => 'Authorization2', '@title' => 'Authorization2', ), ), );
期望输出
$resources = [ 0 => [ 'parent' => null, 'resource' => 'Authorization'], 1 => [ 'Authorization' => 'Authorization', 'resource' => 'Authorization2'] ];
现有问题代码
目前编写的递归方法只能提取所有资源项,无法为存在父级的资源正确绑定父级信息,代码如下:
public function array_values_recursive($array) { $flat = array(); foreach($array as $key => $value) { if (is_array($value)) { $flat = array_merge($flat, $this->array_values_recursive($value)); } else { if($key === '@id') { $flat[]['value'] = $value; } } } return $flat; }
解决方案
原实现无法正确绑定父级的核心原因有两点:
- 递归过程中没有传递当前遍历节点的父资源ID上下文,遍历到子节点时丢失了上层关联信息
- 无差别递归所有数组结构,没有针对
resource嵌套字段做层级识别,无法定位正确的父子从属关系
调整递归逻辑,新增父级ID传参、结果集引用传参,遍历到有效资源节点时先组装当前节点的扁平结构存入结果,再将当前节点ID作为父级参数传入下一层嵌套的递归处理即可,支持任意层级嵌套。
修正后的完整实现代码:
public function flattenResources(array $nestedArray, ?string $parentId = null, array &$result = []): array { foreach ($nestedArray as $item) { if (!is_array($item) || !isset($item['@id'])) { continue; } $currentId = $item['@id']; // 组装当前节点结构 $currentNode = ['resource' => $currentId]; if ($parentId === null) { $currentNode['parent'] = null; } else { $currentNode[$parentId] = $parentId; } $result[] = $currentNode; // 存在嵌套子资源时,携带当前ID作为父级继续递归 if (isset($item['resource']) && is_array($item['resource'])) { $this->flattenResources([$item['resource']], $currentId, $result); } } return $result; }
调用方式
直接传入原始嵌套数组调用即可:
$resources = $this->flattenResources($array);
传入示例输入执行后,返回结果和期望结构完全匹配,任意深度的resource嵌套都可以正确生成带父级关联的扁平数组。
内容的提问来源于stack exchange,提问作者L01C
相关产品推荐
相关产品推荐

