← PHP array_product()函数:计算数组元素乘积的用法与实战注意点 PHP array_rand()函数:从数组中随机抽取键名的实用教程 →

PHP array_push()函数:向数组末尾追加元素的正确姿势

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

一、为什么要单独讲array_push()

很多初学者对array_push()的印象停留在"往数组里加东西",但真正写项目时会遇到几个问题:

  • 追加元素后数组的键名到底怎么变?

  • 关联数组和索引数组混用时,追加行为是否一致?

  • 只追加一个元素时,用array_push()和$arr[]=$val到底该选哪个?

  • array_push()的返回值是什么,能不能拿来做判断?

这些问题在手册里分散在不同位置,项目开发中一旦用错,轻则数组结构不符合预期,重则接口返回的JSON键名错乱。下面按实际使用顺序展开。

二、函数原型与参数说明

array_push(array &$array, mixed ...$values): int
参数 说明 是否必需
array 待操作的数组,以引用方式传入 必需
values 要追加的一个或多个值 至少一个

返回值:返回追加完成后数组的元素总个数,类型为int。

这里有两个细节值得注意:

第一个细节是引用传参。&$array表示函数内部直接修改原数组,不需要接收返回值再赋值。也就是说下面两种写法效果不同:

// 写法 A:原数组被修改
array_push($lang, 'laravel');

// 写法 B:原数组不变,$result 是元素个数
$result = array_push($lang, 'laravel');

写法B里$result拿到的是数字,不是数组。这一点在调试时容易看错。

第二个细节是可变参数。PHP4时代array_push()的签名只支持一次追加一个元素,后来才支持一次传多个值。所以一次追加多个元素时,不需要写多次调用。

三、键名变化规则

这是array_push()最容易被忽略的地方。它追加元素时,始终使用"下一个可用的整数键",不会去覆盖已有的字符串键,也不会去填补被unset掉的空洞。

<?php
$lang = array("a" => "php", "b" => "java");
array_push($lang, "laravel", "bluej");
print_r($lang);

输出:

Array
(
    [a] => php
    [b] => java
    [0] => laravel
    [1] => bluej
)

关联键a、b保留,新元素从整数0开始编号。这说明array_push()并不关心原数组是索引数组还是关联数组,它只认"下一个整数键"。

再看一个unset后的情况:

<?php
$car = array('tata', 'honda', 'nexon');
unset($car[2]);
array_push($car, 'city');
print_r($car);

输出:

Array
(
    [0] => tata
    [1] => honda
    [2] => city
)

被删除的2号位置不会被跳过,新元素依然落在2号键上。原因是PHP内部维护了一个nextfreeindex,unset不会把这个指针往回退。如果项目里依赖键名做映射,这一点要特别小心。

四、与$arr[]=$val的对比

这是实际写代码时最常做的选择。两者都能往数组末尾加元素,但差异明显:

对比项 array_push() $arr[]=$val
追加单个元素 可以 可以
追加多个元素 一次调用完成 需要写多行
函数调用开销 有 无
返回值 新长度 赋值表达式的值
可读性 明确表达"追加"语义 更简洁

个人经验:单个元素追加用$arr[]=$val,多个元素追加用array_push()。原因不是性能,而是语义清晰。前者是语言结构,后者是函数调用。在循环里逐条追加数据时,$arr[]=$row比array_push($arr,$row)少一次函数调用,在数据量大的场景下差距会体现出来。

有一个踩坑经历值得分享:曾经在一个数据导出脚本里,循环10万次用array_push()逐条追加,执行时间比改成$arr[]=多了将近一倍。后来查资料确认,array_push()每次调用都要做参数解析和引用处理,而[]是编译期直接生成opcode。数据量小看不出,量大就很明显。

五、项目实例

实例一:代码号学习编程·标签合并

<?php
$tags = ['php', 'mysql'];
$newTags = ['redis', 'nginx'];

foreach ($newTags as $tag) {
    array_push($tags, $tag);
}
print_r($tags);

输出:

Array
(
    [0] => php
    [1] => mysql
    [2] => redis
    [3] => nginx
)

这个写法没问题,但如果只是合并两个数组,用array_merge()更直接。array_push()适合"逐个条件判断后再决定是否追加"的场景。

实例二:代码号学习编程·购物车追加商品

<?php
$cart = [
    ['id' => 101, 'name' => '机械键盘'],
];

$newItem = ['id' => 102, 'name' => '无线鼠标'];
array_push($cart, $newItem);

print_r($cart);

输出:

Array
(
    [0] => Array
        (
            [id] => 101
            [name] => 机械键盘
        )

    [1] => Array
        (
            [id] => 102
            [name] => 无线鼠标
        )
)

这里数组元素本身是关联数组,array_push()追加的是整个子数组,不会打散内部结构。这点和array_merge()的行为不同,后者在合并时会对外层数字键重新编号,但不会递归合并。

实例三:代码号学习编程·批量追加并获取数量

<?php
$subject = ['c', 'java'];
$count = array_push($subject, 'os', 'compiler');

echo $count; // 4
print_r($subject);

返回值4表示追加后总共4个元素。如果项目里需要判断"追加后是否达到某个阈值",可以直接用返回值,不必再调count()。

六、容易混淆的几个函数

  • array_merge():合并两个或多个数组,数字键重新编号,字符串键后者覆盖前者。适合"拼接"语义。

  • array_unshift():在数组开头插入元素,数字键全部重新编号,开销比array_push()大。

  • array_pop():从末尾弹出一个元素,与array_push()方向相反。

  • $arr[]=:语言结构,单元素追加的优选。

选择原则:末尾追加用array_push()或[];开头插入用array_unshift();数组合并用array_merge()。不要用array_push()去做合并,那样写出来的代码既长又慢。

七、本节课程知识要点

  1. array_push()以引用方式修改原数组,返回新长度而非数组本身。

  2. 追加时使用下一个可用整数键,不覆盖字符串键,不填补unset空洞。

  3. 单个元素追加优先用$arr[]=$val,多个元素追加用array_push()。

  4. 大数据量循环追加时,[]的性能优势明显。

  5. 需要合并数组时用array_merge(),不要用array_push()循环追加。

  6. 关联数组追加后,新元素从0开始编号,接口输出前要确认键名结构。

八、常见问题

问:array_push()能不能追加一个数组进去?

可以,但追加的是整个数组作为一个元素。如果想要把数组里的每个值都追加进去,需要用循环或array_merge()。

问:array_push()对空数组有效吗?

有效。空数组追加后,元素从0开始编号。

问:为什么追加后键名不是从原来的较大值加一?

如果原来的键名不连续,PHP会使用内部维护的nextfreeindex,而不是"当前较大键+1"。unset操作不会回退这个指针,所以行为可能和直觉不一致。

← PHP array_product()函数:计算数组元素乘积的用法与实战注意点 PHP array_rand()函数:从数组中随机抽取键名的实用教程 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号