
你在做购物车、标签列表或者后台数据清洗时,常常需要从一个数组里去掉某些元素:可能是按下标删掉某一项,也可能是按值把「苹果」从水果列表里剔除,还可能是按条件批量清理。PHP删除数组元素,核心是用对三个函数:unset 按键删、array_splice 按位置删并重建索引、array_filter 按条件过滤。
本文基于 PHP 7.4 及以上版本验证,覆盖上面三种做法,并附上横向对比和踩坑清单。看完你不仅能写出正确的删除代码,还能理解「按键删」和「按值删」的根本区别,下次处理列表数据可以自己选型。今天这篇文章,编程狮就把这块讲透。
一、先分清两种删除语义
所谓 PHP删除数组元素,本质上分两类:一类是「我知道下标,按位置删」,比如删掉第 3 项;另一类是「我知道值,按内容删」,比如把列表里的 "apple" 去掉。两类用的方法完全不同,搞混了就会删错。
如果你想先系统学数组,可以先过一遍 PHP 教程 里数组章节,把索引数组和关联数组的区别理清,后面理解删除行为会更轻松。
1.1 按键删和按值删的差异
| 维度 | 按键删除 | 按值删除 |
|---|---|---|
| 已知条件 | 元素的下标 | 元素的内容 |
| 典型函数 | unset |
array_splice / array_filter |
| 是否重建索引 | 否(会留空洞) | array_splice 会重建 |
⚠️ 注意:
unset删掉元素后,数组不会自动把后面的下标往前挪。例如删掉下标 1,原来的下标 2、3 仍然叫 2、3,中间会留下一个「空洞」。这在for循环按连续下标遍历时容易踩坑。
1.2 一个常见误解
很多新手以为 unset($arr[1]) 之后数组就变成「紧凑」的了。其实 unset 只是把那一个键去掉,下标序列并不会重排。需要连续下标时,要额外用 array_values 重新索引,这一点我们第三节会展开讲。
二、方法一:unset 按键删除(最直白)
unset 是 PHP 里删除变量和数组元素最常用的语言结构。给它一个数组下标,它就移除那个位置的元素,语法简单、性能好,是日常删除的首选。
<?php
$fruits = ["apple", "banana", "orange", "grape"];
unset($fruits[1]); // 删掉 "banana"
print_r($fruits);
?>
上面这段做的是:把下标为 1 的 "banana" 移除。输出里 banana 不见了,但下标仍然保留为 0 => apple、2 => orange、3 => grape,下标 1 成为空洞。
这里有个细节:unset 操作的是「变量当前绑定的那个数组」。如果同一个数组被多个变量引用(比如用 =& 赋值),unset 其中一个并不会销毁底层数据,只是断开那一个引用。理解这一点,能避免很多「我明明 unset 了怎么还在」的困惑。
正因为 unset 不重排,如果你接下来要继续用数组,往往要补一步重整:
<?php
$fruits = ["apple", "banana", "orange", "grape"];
unset($fruits[1]);
$fruits = array_values($fruits); // 重新索引,变成 0,1,2
print_r($fruits);
?>
💡 小提示:如果你接下来要用
for ($i = 0; $i < count($fruits); $i++)遍历,记得在unset后补一句array_values,否则会因为下标不连续而漏掉元素。顺手记函数用法可以翻 PHP 速查手册。
三、方法二:array_splice 按位置删除(自动重排)
array_splice 可以「从某个位置起,删除 N 个,并可插入新元素」。它删完会自动把后面的元素往前挪,下标重新变连续,比 unset + array_values 一步到位,适合「删完就要紧凑数组」的场景。
<?php
$fruits = ["apple", "banana", "orange", "grape"];
array_splice($fruits, 1, 1); // 从下标1开始,删1个
print_r($fruits); // ["apple", "orange", "grape"]
?>
上面这段做的是:从下标 1 起删除 1 个元素,结果下标自动重排为 0,1,2,无需手动 array_values。
⚠️ 注意:
array_splice会修改原数组并返回被删部分,且对关联数组会忽略字符串键、按数字顺序处理。如果你的数组是"a" =& 1这种关联结构,优先用unset而不是array_splice,否则可能删错位置。
四、方法三:array_filter 按条件过滤(批量清理)
当你想「删掉所有满足某条件的元素」而不是只删一个,array_filter 最合适。它接收一个回调函数,返回 true 的元素保留,false 的被剔除,非常适合按规则批量清理。
<?php
$numbers = [1, 2, 3, 4, 5, 6];
$even = array_filter($numbers, function ($n) {
return $n % 2 === 0; // 只保留偶数
});
print_r($even); // [2, 4, 6]
?>
上面这段做的是:用回调保留所有偶数,奇数被过滤掉。它不会改动原数组,而是返回一个新数组,原数组保持完整。想系统练数组函数,可以配合 PHP数组操作笔记 这类实操笔记,把数组的常见操作一次练熟。
| 方法 | 按什么删 | 是否重排下标 | 适合场景 |
|---|---|---|---|
unset |
按键(下标) | 否 | 删单个已知位置 |
array_splice |
按位置 + 数量 | 是 | 删单个并要紧凑 |
array_filter |
按条件 | 否(保留原键) | 批量按规则清理 |
表:三种删除方法横向对比。删单个已知位置用 unset,删完要紧凑用 array_splice,按规则批量清理用 array_filter。

五、踩坑清单
把读者最容易卡住的三个点列出来:
- 空洞导致遍历漏项:
unset后直接for连续下标遍历会漏掉后面的元素,记得array_values。 - 关联数组误用 splice:
array_splice对字符串键不敏感,关联数组请坚持用unset。 - array_filter 保留原键:过滤后的数组键可能不连续(如只留了偶数下标),需要连续键时同样用
array_values重整。 - 用错等号比较:判断「是否删成功」时别用
==和null比,未定义下标返回null和「删掉了值恰好是 null」容易混淆,建议用array_key_exists判断键是否还在。
总结
PHP删除数组元素,删单个已知位置用 unset,删完要紧凑下标就上 array_splice,按规则批量清理用 array_filter。三者核心差别在于「按键还是按值、是否重排下标」。
要点带走:
unset留空洞,连续遍历前务必array_values;- 关联数组优先
unset,别用array_splice; array_filter不改原数组,返回新数组。
把 PHP数组操作 的整体逻辑理清,你的 PHP基础 也会更扎实。下一步建议把数组常用函数整体过一遍,再去看 PHP 教程里关于数组遍历的章节,处理列表数据会更顺手。
一句话选型:删单个已知位置用 unset 后补 array_values;删完要紧凑下标上 array_splice;按规则批量清理用 array_filter。关联数组一律用 unset,别碰 array_splice。
延伸学习
想把 PHP 数组删除与整体处理这块系统补齐,可以按这个顺序来:
- 想系统练数组函数,可以配合 PHP 数组长度怎么获取 这类实操笔记巩固;
- 想动手练,PHP 零基础入门课程 是边学边写的形式,适合巩固。
常见问题
Q:unset 之后为什么下标不连续了?
A:因为 unset 只移除指定键,不会把后续元素前移。需要连续下标时,用 array_values($arr) 重新索引即可。
Q:怎么一次删掉多个指定下标的元素?
A:可以多次 unset($arr[$i]),或者改用 array_splice 配合循环;更简洁的是用 array_filter 按「保留哪些」的反向条件过滤。
Q:array_filter 把空字符串也过滤掉了,正常吗?
A:正常。array_filter 默认把空值(空字符串、0、null、false)都视为 false 而剔除。要保留这些值,需显式写回调判断,例如 function ($v) { return $v !== null; }。
Q:关联数组能用 array_splice 吗?
A:不推荐。array_splice 按数字顺序处理,会忽略字符串键,可能删错位置。关联数组请始终用 unset。

免费 AI IDE



