PHP 怎么删除数组里指定的元素?附 3 种方法讲清楚

编程狮(w3cschool.cn) 2026-08-20 15:14:15 浏览数 (37)
反馈

PHP 怎么删除数组里指定的元素?

你在做购物车、标签列表或者后台数据清洗时,常常需要从一个数组里去掉某些元素:可能是按下标删掉某一项,也可能是按值把「苹果」从水果列表里剔除,还可能是按条件批量清理。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 => apple2 => orange3 => 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。

PHP 删除数组元素的三种方法怎么选?

五、踩坑清单

把读者最容易卡住的三个点列出来:

  • 空洞导致遍历漏项unset 后直接 for 连续下标遍历会漏掉后面的元素,记得 array_values
  • 关联数组误用 splicearray_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 数组删除与整体处理这块系统补齐,可以按这个顺序来:

  1. 想系统练数组函数,可以配合 PHP 数组长度怎么获取 这类实操笔记巩固;
  2. 想动手练,PHP 零基础入门课程 是边学边写的形式,适合巩固。

常见问题

Q:unset 之后为什么下标不连续了?
A:因为 unset 只移除指定键,不会把后续元素前移。需要连续下标时,用 array_values($arr) 重新索引即可。

Q:怎么一次删掉多个指定下标的元素?
A:可以多次 unset($arr[$i]),或者改用 array_splice 配合循环;更简洁的是用 array_filter 按「保留哪些」的反向条件过滤。

Q:array_filter 把空字符串也过滤掉了,正常吗?
A:正常。array_filter 默认把空值(空字符串、0nullfalse)都视为 false 而剔除。要保留这些值,需显式写回调判断,例如 function ($v) { return $v !== null; }

Q:关联数组能用 array_splice 吗?
A:不推荐。array_splice 按数字顺序处理,会忽略字符串键,可能删错位置。关联数组请始终用 unset

1 人点赞