array_pop从末尾移除元素,o(1)且不重排键;array_shift从开头移除元素,o(n)且重置数字键、保留字符串键;两者均修改原数组并返回被删元素,空数组时返回null。

array_pop 和 array_shift 都会修改原数组,但操作位置完全不同
array_pop 永远作用于数组末尾:移出最后一个元素,返回它,并让数组长度减一。数字键和字符串键都不重排,只把「下一个插入位置」的索引更新(比如原数组有 4 个元素,array_pop 后 count() 变 3,内部指针也移到新末尾)。
array_shift 则从开头动手:移出第一个元素,返回它,其余元素整体前移一位。关键区别在于——所有数字键会被强制重置为 0, 1, 2, ...;而字符串键(如 'name'、'id')保持不变。
两者都是引用传参(array &$array),不加 & 会触发 E_WARNING 并静默失败(PHP 8+ 更严格)。
性能差异巨大:小数组看不出,大数组必须警惕
array_pop 是 O(1) 操作:它只读取并删除最后一个元素,不遍历、不重索引。
array_shift 是 O(n) 操作:它必须把剩下所有元素向前挪一位,再逐个重写数字键。对 10 万条记录的索引数组调用一次 array_shift,可能比 array_pop 慢上百倍。
- 若你只是想“取头但不真删”,用
$arr[0]或reset($arr)更快 - 若需频繁从头部增删(如队列),考虑用 SplQueue;或改用
array_reverse() + array_pop()组合(仅当无法换数据结构时) - PHP 8.1+ 的
array_key_first()/array_key_last()可安全获取键名,避免触发重索引
字符串键数组里,array_shift 的行为容易被误判
很多人以为 array_shift 会“删掉第一个键值对”,其实它删的是「按内部顺序第一个出现的元素」,而这个顺序和键名无关。例如:
$arr = ['z' => 'last', 'a' => 'first', 'm' => 'middle']; $val = array_shift($arr); // $val === 'first',不是 'last' // $arr 现在是 ['m' => 'middle', 'z' => 'last'] —— 字符串键没重排,但顺序变了
这种行为在关联数组中尤其隐蔽:你删的不是「键最小的那个」,而是「当前数组迭代器指向的第一个」。如果之前执行过 end() 或 next(),array_shift 的结果可能完全不符合直觉。
真正安全的头部访问方式是:current($arr) 配合 key($arr),而不是依赖 array_shift 的副作用。
别忽略 NULL 返回值和类型陷阱
两个函数在空数组或非数组输入时都返回 NULL,但 PHP 类型系统不会帮你报错:
- 传入
null、false、字符串,array_shift会静默返回NULL,不抛异常 - 用
===判断返回值是否为NULL,避免==把0、''、false误判为失败 - PHP 8+ 开启严格模式后,传错类型会触发
TypeError;但默认仍容忍弱类型输入
最常被忽略的一点:这两个函数都不检查数组是否「有元素可删」,它们只管执行逻辑。业务代码里该加 !empty($arr) 判断的地方,不能靠函数自己兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











