← PHP array_search()函数教程:数组值查找与键名返回实战 PHP shuffle()函数教程:数组随机打乱、键名重建与业务场景实战 →

PHP array_shift()函数教程:移除数组首元素与键名重建实战

著
原创 2026-10-09 PHP 已有人查阅

一、函数定位与基本概念

array_shift()是PHP内置的数组操作函数,用于将数组开头的第一个元素移出,并返回被移除元素的值。这个函数从PHP4.0开始提供,属于数组头部操作的常用工具。

函数原型如下:

mixed array_shift ( array &$array );

参数说明:

参数 说明 是否必需
array 指定的输入数组,以引用方式传入 必需

返回值方面,array_shift()返回被移除元素的值。如果传入的数组为空,则返回NULL。

这里有一个需要重点关注的机制:如果数组使用的是数字键,移除首元素后,剩余所有元素会重新从0开始编号,依次递增1。这个行为是array_shift()与unset()的关键区别。unset()删除元素后不会重建键名,而array_shift()会。

参数以引用方式传入,意味着函数内部直接修改原数组,调用时不需要接收返回值来覆盖原变量。这一点和array_slice()这类返回新数组的函数有本质不同。

二、基础用法与代码号学习编程示例

先看一个数字索引数组的例子。代码号学习编程时,常用待办事项列表来演示数组头部删除:

<?php
$task = array(0 => "写作业", 1 => "看书", 2 => "跑步");
echo array_shift($task);
print_r($task);
?>

输出结果为:

写作业Array
(
    [0] => 看书
    [1] => 跑步
)

array_shift()移除了键名0对应的"写作业",并把这个值返回。剩余两个元素的键名被重新索引为0和1。

再看一个包含返回值处理的例子:

<?php
$subject = array(0 => 'science', 1 => 'math', 2 => 'english', 3 => 'hindi');
$result = array_shift($subject);
print_r($subject);
print_r($result);
?>

输出结果为:

Array
(
    [0] => math
    [1] => english
    [2] => hindi
)
science

这里把返回值赋给了$result,原数组$subject被直接修改。注意输出顺序:先打印修改后的数组,再打印被移除的值。这说明array_shift()的副作用发生在函数调用那一刻,后续代码使用的是已经变化的数组。

三、关联数组中的表现

array_shift()同样适用于关联数组。关联数组的键名是字符串,移除首元素后,剩余元素的字符串键名保持不变,不会发生重建。

<?php
$score = array("sachin" => 200, "sehwag" => 400, "ganguly" => 500, "yuvraj" => 100);
print_r(array_shift($score));
print_r($score);
?>

输出结果为:

200Array
(
    [sehwag] => 400
    [ganguly] => 500
    [yuvraj] => 100
)

sachin对应的200被移除,剩下三个键名原样保留。这里可以看出数字键重建规则只针对数字键,字符串键不受影响。

再看一个公司名称数组的例子:

<?php
$company = array(0 => "TCS", 1 => "Infosys", 2 => "Mindtree");
print_r(array_shift($company));
print_r($company);
?>

输出结果为:

TCSArray
(
    [0] => Infosys
    [1] => Mindtree
)

原本键名1和2的元素,移除首元素后变成了0和1。如果后续代码依赖固定的键名,这种重建会带来问题。

四、数字键重建的实战影响

数字键重建是array_shift()最容易引发问题的地方。项目实战中有一次处理队列任务时,任务列表用数字索引数组存储,每次取出第一个任务执行。代码逻辑是取出后根据键名去另一个映射表里查配置。结果第一次取出后键名重建,后续任务的键名全部偏移,导致映射查询错位。

这个踩坑经历说明:如果数组的键名本身承载业务含义,比如和另一个数组的键对应,那么使用array_shift()前需要确认键名重建是否会影响后续逻辑。如果键名需要保持稳定,应该考虑使用unset()配合reset()读取首元素,或者改用关联数组。

另一个场景是分页数据。从数据库查询结果集中取第一条记录时,有人习惯用array_shift()。但如果结果集是数字索引数组,移除后键名重建,后续如果还有基于原始键名的操作,就会出现不一致。

个人建议:array_shift()适合那种只关心元素值、不关心键名的场景。比如队列消费、消息轮询、任务依次处理。如果键名有业务意义,使用前先评估重建带来的影响。

五、与相关函数的对比选择

array_shift()和几个函数容易混淆,需要分清使用场景。

array_shift()与array_pop():array_shift()移除数组第一个元素,array_pop()移除之后一个元素。两者都返回被移除的值,都会修改原数组。区别在于操作位置和性能。array_shift()因为需要重建所有数字键,时间复杂度是O(n)。array_pop()只操作末尾,不需要重建键名,时间复杂度是O(1)。如果数据量较大且操作频繁,array_pop()的性能优势明显。

array_shift()与unset():unset($array[0])只删除指定键的元素,不重建键名,也不返回值。array_shift()会返回值并重建数字键。需要获取被删除的值时,array_shift()更直接。

array_shift()与array_slice():array_slice($array,1)返回一个去掉首元素的新数组,原数组不变。array_shift()直接修改原数组。如果希望保留原数组,array_slice()更合适。

array_shift()与array_key_first():PHP7.3之后提供了array_key_first(),可以只读取第一个键名而不修改数组。如果只是想查看首元素而不删除,array_key_first()配合$array[array_key_first($array)]是更轻量的做法。

个人见解:array_shift()的引用传参设计意味着它天然带有副作用。在函数式编程风格中,这种副作用需要谨慎对待。团队协作时,如果函数内部调用了array_shift(),应该在注释或文档中标注原数组会被修改,避免调用方误用。

六、空数组与边界处理

array_shift()对空数组的处理是返回NULL。这个行为需要和返回值为NULL的正常元素区分开。

<?php
$emptyArray = array();
$result = array_shift($emptyArray);
var_dump($result);
?>

输出结果为:

NULL

如果数组中第一个元素的值本身就是NULL,array_shift()也会返回NULL。这时候无法仅凭返回值判断数组是否为空。需要结合count()或empty()在调用前先做判断。

项目实战反思:在处理外部数据时,数组可能为空,也可能首元素为NULL。如果直接依赖array_shift()的返回值做分支判断,容易把“空数组”和“首元素为NULL”两种情况混为一谈。比较稳妥的做法是先检查数组是否为空,再执行移除操作。

array_shift()的参数是引用传递,传入的必须是变量,不能是函数调用的直接结果或字面量数组。类似array_shift(array(1,2,3))这样的写法在较新的PHP版本中会报错,因为不能引用临时值。

七、本节课程知识要点

  • array_shift()移除数组第一个元素并返回其值,原数组以引用方式被修改。

  • 数字键数组在移除首元素后,剩余元素的键名会从0开始重新索引。

  • 关联数组的字符串键不受重建规则影响,键名保持不变。

  • 空数组调用array_shift()返回NULL,首元素为NULL时返回值也是NULL,需要区分。

  • array_shift()的时间复杂度为O(n),频繁操作大数组时性能不如array_pop()。

  • 键名有业务含义时,使用array_shift()前需要评估键名重建的影响。

  • 只想查看首元素而不删除时,可以考虑array_key_first()。

  • 函数参数以引用传入,只能传变量,不能传临时值。

array_shift()的用法本身不复杂,关键在于理解它的两个特性:引用修改原数组和数字键重建。把这两个特性放到具体业务场景中评估,就能判断它是否适合当前需求。如果只是简单地从头部取一个值并删除,array_shift()是直接的选择。如果键名稳定性重要,或者需要保留原数组,就应该考虑其他方案。

← PHP array_search()函数教程:数组值查找与键名返回实战 PHP shuffle()函数教程:数组随机打乱、键名重建与业务场景实战 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号