PHP 里删数组元素看着简单,unset 一下就行,但删完之后索引断档,JSON 输出变成对象,前端拿到又报错。所以「怎么删」得看你要的结果是什么。

场景一:知道键名

$arr = ['name' => '张三', 'age' => 20, 'city' => '上海'];
unset($arr['age']);

关联数组直接 unset,最干净。索引数组 unset 之后键不连续,后面接 for 循环会出问题。

场景二:知道值,按值删除

$arr = [1, 2, 3, 2];
// 删除所有值为 2 的元素
$arr = array_filter($arr, fn($v) => $v !== 2);

// 只删第一个匹配
$k = array_search(2, $arr, true);
if ($k !== false) unset($arr[$k]);
$arr = array_values($arr);

array_search 返回的键可能是 0,所以判断必须用 !== false,用 !$k 会把下标 0 的元素误判成不存在。这是 PHP 里最经典的坑之一。

场景三:批量删多个值

$arr = array_diff($arr, [2, 5]);
$arr = array_values($arr);

array_diff 按值比较,保留第一个数组里不在后面数组中的元素,适合一次删掉一批。

场景四:按条件删(比如删空值、删重复)

$arr = array_filter($arr);        // 删掉 false、null、''、0
$arr = array_unique($arr);        // 按值去重
$arr = array_values($arr);        // 重建索引

注意 array_filter 不带回调会连 0 和字符串 0 一起删,数字数组里要传显式的条件。

场景五:删完要重新索引

只要是 unset 或者 array_filter 操作过索引数组,末尾加一句 array_values($arr),键就重新从 0 排好。输出 JSON 时这一步几乎必须,否则 json_encode 会把数组变成对象,键不连续,前端判断数组类型就会失败。

性能上的提示

在 for 循环里边遍历边 unset 是最容易出错的做法,元素会跳过。需要边遍历边删,就倒序遍历,或者先收集要删的键,循环结束后统一清理。数据量大时,array_filter 比多次 unset 更快。

总结:删键用 unset,删值用 array_search 或 array_filter,最后统一 array_values 重建索引。