空容器的魔法:如何让 PHP 为你工作
\n\n想象一下:你正在编写一个 PHP 脚本,需要收集数据——例如购物车中的商品 ID。你创建一个空数组,然后在循环中向其中添加元素。看起来再简单不过了?但正是这个时刻——向空 PHP 数组添加元素——在 Stack Overflow 上引发了成千上万个问题。为什么?因为新手经常混淆语法,而有经验的开发者则想了解底层发生了什么。
\n\n在本文中,我们不仅会展示如何正确编写代码。我们还将深入 PHP 核心(Zend Engine),分析 $arr[] = $value 与 array_push() 的区别,并了解 PHP 8.1 带来了哪些惊喜。准备好了吗?开始吧!
最常见的问题:如何添加元素?
\n\n如果你是新手,那么首先想到的可能是写出类似这样的代码:
\n\n<?php\n$myArray = array(); // 空数组\n$myArray[] = '第一个元素';\n$myArray[] = '第二个元素';\nprint_r($myArray);\n?>\n\n这段代码将输出:
\n\nArray\n(\n [0] => 第一个元素\n [1] => 第二个元素\n)\n\n能工作吗?是的。但为什么呢?让我们分析一下 [] 运算符实际上做了什么。
运算符 $arr[] = $value:快速而优雅
\n\n当你编写 $arr[] = $value 时,PHP 不会调用任何函数。相反,它直接访问数组的内部数据结构(在 Zend Engine 中称为 zend_array)。
底层发生了什么:
\n- \n
- PHP 检查数组是否存在。如果不存在,则创建一个新数组(但最好始终显式初始化:
$arr = [])。 \n - 将元素添加到数组末尾,自动分配下一个数字键(0, 1, 2...)。 \n
- 如果数组是空的——第一个元素获得键
0。 \n - 没有函数调用的额外开销。这是性能最高的方式。 \n
建议:当你只需要在末尾添加一个元素时,始终使用 $arr[] = ...。它快速、可读性强,且无需导入函数。
array_push():当需要一次添加多个元素时
\n\n第二种流行的方法是使用 array_push() 函数:
<?php\n$myArray = [];\narray_push($myArray, '第一个', '第二个', '第三个');\nprint_r($myArray);\n?>\n\n结果相同。但有一些细节:
\n- \n
array_push()通过引用接收数组,并将所有传递的值添加到末尾。 \n - 它返回数组中新的元素数量(从 PHP 7.3 开始)。 \n
- 底层原理:该函数为每个元素调用内部过程
zend_hash_next_index_insert。这意味着,如果你只添加一个元素,由于函数调用的额外开销,array_push()比$arr[] = ...稍慢。 \n
何时使用:仅当你需要一次添加多个元素(2 个或更多)时。对于单个元素——忘记 array_push,使用 []。
空数组和键:如果键不是数字怎么办?
\n\n如果你想添加一个带有特定键的元素呢?例如,关联数组:
\n\n<?php\n$user = [];\n$user['name'] = '伊万';\n$user['age'] = 30;\n?>\n\n这里也很简单。带有方括号内键的 [] 运算符($arr['key'] = value)的工作方式类似于赋值。如果键不存在——则创建它。如果存在——则覆盖它。
但要小心:如果你在关联数组旁边不小心写了 $user[] = '值',PHP 将添加一个数字键