You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何动态遍历多维数组提取数据 适配array_map/array_walk

问题结论

该需求完全可实现,无需编写固定层数的嵌套循环,既可以封装成兼容array_map/array_walk的回调函数,也可以通过递归、PHP内置迭代器两种方案实现任意层级的动态遍历,适配频繁变动的层级参数。

实现方案

方案1:递归实现(逻辑最直观,适配动态参数)

递归是处理未知层级多维数组的通用方案,将目标层级数作为可变参数传入,遍历到对应层级时提取所需数据即可,无需提前写死循环层数。
以下代码完全兼容原有逻辑中「父路径键不重复」的判断规则:

/**
 * 动态层级遍历多维数组
 * @param array $data 待遍历原始数组
 * @param int $targetDepth 目标遍历层级,可动态修改
 * @param array $currentPath 当前遍历路径栈,递归内部使用
 * @param array $result 遍历结果集,递归内部使用
 * @return array
 */
function traverseDynamic(array $data, int $targetDepth, array $currentPath = [], array &$result = []): array
{
    $currentDepth = count($currentPath);
    // 到达目标层级,记录路径或提取业务字段
    if ($currentDepth === $targetDepth) {
        $result[] = $currentPath;
        return $result;
    }
    foreach ($data as $key => $value) {
        // 跳过已在父路径中存在的键,和原代码判断逻辑一致
        if (in_array($key, $currentPath)) {
            continue;
        }
        $newPath = $currentPath;
        $newPath[] = $key;
        traverseDynamic($data, $targetDepth, $newPath, $result);
    }
    return $result;
}

// 调用示例:需要3层遍历就传3,需要其他层级直接修改第二个参数即可
$hold = traverseDynamic($data, 3);

如果需要封装为array_map/array_walk可调用的结构,只需用闭包绑定可变参数即可:

$targetDepth = 3; // 该参数可随时修改
$result = [];
$walkCallback = function ($value, $key) use ($data, $targetDepth, &$result) {
    if (!in_array($key, [])) {
        traverseDynamic($data, $targetDepth, [$key], $result);
    }
};
array_walk($data, $walkCallback);

如果需要提取示例数组中的业务字段(比如loc.type、rel.id),只需修改到达目标层级时的逻辑,直接读取对应键值即可:

// 替换递归方法中到达目标层级的分支逻辑即可
if ($currentDepth === $targetDepth) {
    $lastItem = end($currentPath);
    $result[] = [
        'path' => $currentPath,
        'type' => $data[$lastItem]['loc']['type'],
        'rel_id' => $data[$lastItem]['rel']['id']
    ];
    return $result;
}

方案2:PHP内置迭代器实现(无递归栈溢出风险)

如果数组层级极深,可使用PHP原生的RecursiveArrayIterator搭配RecursiveIteratorIterator实现遍历,无需自行维护递归逻辑,避免深层递归带来的栈溢出问题:

function traverseWithIterator(array $data, int $targetDepth): array
{
    $result = [];
    $iterator = new RecursiveIteratorIterator(
        new RecursiveArrayIterator($data),
        RecursiveIteratorIterator::SELF_FIRST
    );
    $pathStack = [];
    foreach ($iterator as $key => $value) {
        // 自动维护对应深度的路径栈
        $depth = $iterator->getDepth();
        $pathStack = array_slice($pathStack, 0, $depth);
        $pathStack[] = $key;
        // 到达目标层级且存在需要的业务字段时,记录数据
        if ($depth === $targetDepth - 1 && isset($value['loc']['type'], $value['rel']['id'])) {
            $result[] = [
                'path' => $pathStack,
                'type' => $value['loc']['type'],
                'rel_id' => $value['rel']['id']
            ];
        }
    }
    return $result;
}
注意事项
  • 上述两种方案都不需要手动调用deleteFromArray维护父路径数组,逻辑会自动处理路径的入栈、出栈,不会出现路径污染问题
  • 调整遍历层级仅需修改传入的$targetDepth参数值,无需改动核心遍历逻辑
  • 可根据业务需求灵活修改目标层级的字段提取规则,适配不同的数据提取场景

内容的提问来源于stack exchange,提问作者mohsen shahbazi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:25:25