Arrays7 min readExamples run on PHP 8.5.10

array_splice()

Learn how array_splice() removes, inserts and replaces elements in place, how offsets and lengths behave, and which key and null pitfalls to avoid.

Signature

array_splice(
    array &$array,
    int $offset,
    ?int $length = null,
    mixed $replacement = []
): array

Purpose

array_splice() edits an array in place. It cuts out a range of elements, optionally puts new elements where the range used to be, and gives you back the elements it cut out. Because one call can delete, insert or replace, it is the general-purpose tool behind array_pop(), array_shift() and array_unshift()-style operations at arbitrary positions.

Signature

The first parameter is taken by reference, so the variable you pass is modified directly. The return value is not the edited array. This is the most common source of confusion with this function.

Parameters and defaults

  • $array: the variable to modify. It must be a variable, not a literal or a function result, because PHP needs something to write back to.
  • $offset: where the removed portion begins. A positive value counts from the start; a negative value counts from the end.
  • $length: how many elements to remove. If omitted or null, everything from $offset to the end is removed. A positive number removes that many elements. A negative number stops the removal that many elements before the end. Zero removes nothing, which turns the call into a pure insertion. Since PHP 8.0 the parameter is nullable.
  • $replacement: elements to put in place of the removed range. It defaults to an empty array. If it is not an array, it is cast with (array). A single scalar therefore works without brackets, but null and objects behave unexpectedly.

Return value and failure cases

The function returns an array of the extracted elements. If nothing was removed, the result is an empty array. The function does not return false for out-of-range positions; it simply works with what exists. Passing a first argument that is not an array raises a TypeError, and passing something that cannot be a reference, such as a literal, is an error.

Numeric keys in the input array are not preserved: after the call, integer keys are renumbered from zero. Keys in the replacement array are ignored as well. String keys in the input stay where they are.

Example 1: remove a range and keep what was removed

The array shrinks and the return value holds the cut portion.

Example
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$colors = ["red", "green", "blue", "yellow"];
$removed = array_splice($colors, 1, 2);
echo json_encode($colors, $flags), "\n";
echo json_encode($removed, $flags), "\n";
Output
["red","yellow"]
["green","blue"]

Example 2: insert and replace

A length of 0 inserts without deleting. A negative offset counts from the end, so -1 points at the last element.

Example
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$queue = ["a", "b", "e"];
array_splice($queue, 2, 0, ["c", "d"]);
echo json_encode($queue, $flags), "\n";

$tail = ["red", "green", "blue", "yellow"];
$gone = array_splice($tail, -1, 1, ["black", "maroon"]);
echo json_encode($tail, $flags), "\n";
echo json_encode($gone, $flags), "\n";
Output
["a","b","c","d","e"]
["red","green","blue","black","maroon"]
["yellow"]

The replacement may be longer or shorter than the removed range, so the array can grow or shrink.

Example 3: keys and null replacements

Integer keys are renumbered while string keys survive. Wrapping null in an array is required if you want to insert a null value.

Example
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$data = ["x" => 1, 5 => "five", 9 => "nine", "y" => 2];
$removed = array_splice($data, 1, 1);
echo json_encode($data, $flags), "\n";
echo json_encode($removed, $flags), "\n";

$items = ["a", "b", "c"];
array_splice($items, 1, 1, [null]);
echo json_encode($items, $flags), "\n";
Output
{"x":1,"0":"nine","y":2}
["five"]
["a",null,"c"]

In the first result, the surviving integer key 9 became 0, while x and y stayed.

Edge cases

  • Offset past the end: the offset is limited to the array size, so the replacement is appended instead of causing an error.
  • Large positive length: a length bigger than what remains simply removes to the end. To remove to the end while also supplying a replacement, count($array) is a clear choice for the length.
  • Negative length: it describes where the removal stops, not how many items to remove. With length -1, the last element is kept.
  • Empty array: inserting into an empty array works and gives the replacement values with fresh keys starting at zero.

Common mistakes

  1. Using the return value as the result. Writing $list = array_splice($list, 1, 1); replaces your array with the removed items. Call the function as a statement and read $list afterwards.
  2. Expecting keys to survive. If your array uses meaningful integer keys such as IDs, the renumbering will destroy that mapping. Choose another approach for keyed data, for example unset() for a single key.
  3. Passing null or an object as the replacement. (array) null is an empty array, so nothing is inserted; an object turns into an array of its properties. Wrap the value: [$value].
  4. Confusing length with an end position. The third argument is a count, not an index, unless it is negative.
  5. Splicing inside a foreach over the same array. Changing the array's structure while iterating is a recipe for skipped or repeated items. Build a new array or loop carefully by index.
  • array_slice() extracts a portion without modifying the original array.
  • array_merge() combines arrays and returns a new one.
  • unset() removes an element by key and does not renumber the rest.
  • array_pop(), array_shift(), array_push() and array_unshift() handle the ends of a list; array_splice() handles any position.

Recap

array_splice() modifies the array you pass by reference and returns the removed elements. Use $offset and $length to pick the range, a length of zero to insert, and an array replacement to substitute elements. Remember that integer keys are renumbered, that null replacements need wrapping, and that the return value is the removed part, not the edited array.

Tested examples

Remove a range and keep the removed elements
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$colors = ["red", "green", "blue", "yellow"];
$removed = array_splice($colors, 1, 2);
echo json_encode($colors, $flags), "\n";
echo json_encode($removed, $flags), "\n";
Output
["red","yellow"]
["green","blue"]
Insert and replace elements
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$queue = ["a", "b", "e"];
array_splice($queue, 2, 0, ["c", "d"]);
echo json_encode($queue, $flags), "\n";

$tail = ["red", "green", "blue", "yellow"];
$gone = array_splice($tail, -1, 1, ["black", "maroon"]);
echo json_encode($tail, $flags), "\n";
echo json_encode($gone, $flags), "\n";
Output
["a","b","c","d","e"]
["red","green","blue","black","maroon"]
["yellow"]
Key renumbering and null replacements
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$data = ["x" => 1, 5 => "five", 9 => "nine", "y" => 2];
$removed = array_splice($data, 1, 1);
echo json_encode($data, $flags), "\n";
echo json_encode($removed, $flags), "\n";

$items = ["a", "b", "c"];
array_splice($items, 1, 1, [null]);
echo json_encode($items, $flags), "\n";
Output
{"x":1,"0":"nine","y":2}
["five"]
["a",null,"c"]