array_walk本身不用于去重,仅遍历执行回调;二维数组去重需配合serialize+array_unique或array_walk构建唯一键索引等逻辑,后者适合按指定字段(如id)保留首次出现项。

array_walk 本身不用于去重,它只是遍历数组并执行回调函数。二维数组去重不能直接靠 array_walk 实现,需配合其他逻辑(如序列化键、唯一标识、或借助 array_unique + 回调)。PHP 7.3 中推荐用 array_unique 配合 SORT_REGULAR 或自定义去重逻辑,array_walk 可作为辅助工具(比如预处理或标记),但不是核心去重手段。
用 array_unique + serialize 去重二维关联数组
这是 PHP 7.3 中最常用、兼容性好且简洁的方法:将每行子数组序列化为字符串,去重后再反序列化还原。
示例代码:
$original = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
['id' => 1, 'name' => 'Alice'], // 重复项
['id' => 3, 'name' => 'Charlie']
];
// 序列化 → 去重 → 反序列化
$serialized = array_map('serialize', $original);
$unique_serialized = array_unique($serialized, SORT_REGULAR);
$deduped = array_map('unserialize', $unique_serialized);
print_r($deduped);
用 array_walk 辅助构建唯一键索引(更可控)
若需按特定字段(如 'id')去重,可用 array_walk 遍历并以该字段为键存入新数组,自动覆盖重复项。适合“保留首次出现”逻辑。
立即学习“PHP免费学习笔记(深入)”;
- 仅适用于有明确唯一标识字段的场景(如 id、email)
- 注意:会丢失原始键名,顺序由遍历决定
- 结果是关联数组,如需重置索引可套用 array_values()
$indexed = [];
array_walk($original, function($item) use (&$indexed) {
if (isset($item['id'])) {
$indexed[$item['id']] = $item; // 用 id 作键,自动去重
}
});
$deduped = array_values($indexed); // 可选:重置为数字索引
避免踩坑:array_walk 不能直接返回新数组
array_walk 修改的是原数组(传引用时),它不返回新数组,也不支持链式调用。想用它“生成”去重结果,必须在回调中手动收集数据(如上面的 $indexed),不能依赖其返回值。
- 不要写:
$result = array_walk(...);—— 它恒返回 true - 不要期望 array_walk 自动过滤或跳过元素;它总是遍历全部
- 去重逻辑必须在回调内显式实现(如检查是否存在、赋值覆盖等)
替代方案:封装成可复用函数
把去重逻辑封装起来,提高可读性和复用性:
function array_unique_by_key(array $array, string $key): array
{
$result = [];
foreach ($array as $item) {
if (isset($item[$key])) {
$result[$item[$key]] = $item;
}
}
return array_values($result);
}
// 使用
$deduped = array_unique_by_key($original, 'id');



















