一、array_splice()是什么
array_splice()是PHP中用于操作数组的内置函数,可以把它看作array_slice()的增强版本。array_slice()只负责“取出一段”,而array_splice()在取出的同时,还会直接修改原数组——删除指定位置的元素,并且可以选择用新的元素替换掉被删除的部分。
这个函数从PHP4开始引入,一直沿用至今,在处理数组的动态增删改场景中非常实用。
二、语法与参数说明
array_splice(array &$input, int $offset, ?int $length = null, mixed $replacement = [])
| 参数 | 说明 | 是否必需 |
|---|---|---|
| array | 要操作的输入数组,以引用方式传入 | 必需 |
| offset | 从哪个位置开始删除元素 | 必需 |
| length | 删除多少个元素,同时决定返回数组的长度 | 可选 |
| replacement | 用这个数组中的元素替换被删除的部分 | 可选 |
返回值:返回一个包含被提取(删除)元素的数组。注意,原数组会被直接修改。
三、核心行为拆解
1.offset与length的配合
-
offset为正数:从数组开头第offset个位置开始。
-
offset为负数:从数组末尾倒数第|offset|个位置开始。
-
length为正数:删除length个元素。
-
length为负数:从offset开始,到距离数组末尾|length|个元素处停止。
-
length省略:从offset一直删除到数组末尾。
2.replacement的插入逻辑
如果offset和length的组合导致没有元素被删除,那么replacement数组中的元素会入到offset指定的位置。这一点在项目里经常用来实现“在数组中间插入新元素”。
3.键名处理
被替换进来的数组,其键名不会被保留。也就是说,replacement数组中的字符串键会被丢弃,值按顺序填入。原数组中字符串键名如果未被删除,则保持不变;如果被删除后又有新元素插入,新元素使用数字键。
四、代码号学习编程示例
示例1:删除末尾元素
<?php
$game = ["AbhinavBindra", "Sushilkumar", "Sanianehwal", "Mary kom"];
array_splice($game, 2);
print_r($game);
输出:
Array
(
[0] => AbhinavBindra
[1] => Sushilkumar
)
从索引2开始删除到末尾,原数组只剩前两个元素。
示例2:保留首尾,删除中间
<?php
$game = ["AbhinavBindra", "Sushilkumar", "Sanianehwal", "Mary kom"];
array_splice($game, 1, -1);
print_r($game);
输出:
Array
(
[0] => AbhinavBindra
[1] => Mary kom
)
offset为1,length为-1,表示从索引1开始,删除到倒数第1个元素之前,也就是删掉索引1和2。
示例3:删除并替换
<?php
$game = ["AbhinavBindra", "Sushilkumar", "Sanianehwal", "Mary kom"];
array_splice($game, 1, count($game), "Vijendersingh");
print_r($game);
输出:
Array
(
[0] => AbhinavBindra
[1] => Vijendersingh
)
从索引1开始,删除等同于数组长度的元素(实际删除到末尾),然后用"Vijendersingh"替换。
示例4:关联数组中的替换与返回值
<?php
$fruit = ["a" => "apple", "b" => "banana", "c" => "grapes", "d" => "mango"];
$fruit1 = ["a" => "orange", "b" => "watermelon"];
print_r(array_splice($fruit, 0, 2, $fruit1));
输出:
Array
(
[a] => apple
[b] => banana
)
返回的是被删除的元素,保留了原数组的键名。而原数组fruit的前两个元素被fruit的前两个元素被fruit1的值替换,fruit1的键名"a"、"b"不会被保留,替换后fruit1的键名"a"、"b"不会被保留,替换后fruit变为:
Array
(
[0] => orange
[1] => watermelon
[c] => grapes
[d] => mango
)
五、项目实战中的经验与反思
1.为什么有时不用array_splice()而用array_slice()+重新赋值?
array_splice()会直接修改原数组,这在某些场景下是优点,但在函数式编程或需要保持原数组不变的场景中,直接修改会带来副作用。如果只是想取出一段而不影响原数组,array_slice()更合适。我曾在处理配置数组时误用array_splice(),导致后续读取配置时发现原数组已被改动,排查了一段时间才定位到问题。
2.替换关联数组时的键名
很多开发者以为replacement数组的键名会保留,实际上不会。如果你需要保留键名,应该使用array_slice()配合array_replace()或者手动构建新数组。这一点在官方文档中虽然有说明,但容易被忽略。
3.length为0的妙用
当length为0时,array_splice()不会删除任何元素,但会把replacement数组插入到offset位置。这个技巧可以用来在数组中间插入元素,比array_merge()拼接再重组更直接。
<?php
$queue = ["A", "B", "D"];
array_splice($queue, 2, 0, "C");
print_r($queue);
输出:
Array
(
[0] => A
[1] => B
[2] => C
[3] => D
)
4.负数offset在项目中的实际价值
处理日志或消息列表时,经常需要“删除之后N条”。使用负数offset可以避免手动计算数组长度:
<?php
$logs = ["log1", "log2", "log3", "log4", "log5"];
array_splice($logs, -2);
print_r($logs);
输出:
Array
(
[0] => log1
[1] => log2
[2] => log3
)
六、本节课程知识要点
-
array_splice()会修改原数组,返回被删除的元素。
-
offset和length支持正负值,组合灵活。
-
replacement数组的键名不会被保留。
-
length为0时可用于纯插入操作。
-
关联数组中使用时,注意原数组键名的保留规则。
-
若不需要修改原数组,优先考虑array_slice()。
七、容易踩坑的地方
-
误以为replacement的键名会保留。
-
忘记array_splice()的第一个参数是引用传递,原数组会变。
-
在foreach循环中直接对原数组使用array_splice(),可能导致遍历结果不符合预期。
-
length省略时默认删除到末尾,而不是删除0个。
array_splice()是PHP数组操作中一个功能密集的函数,掌握它的参数组合和行为细节,可以在处理数组增删改时少写很多冗余代码。理解它和array_slice()的分工,注意引用传参和键名处理,就能在项目中用得更加稳妥。