Signature
array_slice(
array $array,
int $offset,
?int $length = null,
bool $preserve_keys = false
): arrayPurpose
array_slice() returns a continuous run of elements from an array. You describe the run with a starting position (offset) and an optional size (length). The original array is never changed; you get a new array containing only the selected elements. It is the usual tool for pagination, "first N items", "last N items" and trimming a list at both ends.
Signature
Parameters and defaults
$array: the input array.$offset: where the slice starts. A non-negative value counts from the beginning. A negative value counts back from the end, so-2starts at the second-to-last element. The offset is a position in the array, not a key.$length: how many elements to take. A positive number means "up to that many"; if fewer remain, you simply get what is available. A negative number means "stop that many elements before the end". Withnull(the default) the slice runs to the end of the array.$preserve_keys: defaults tofalse. When false, integer keys in the result are renumbered from 0. When true, the original integer keys are kept. String keys are always kept, whatever you pass.
Return value and failure cases
The function always returns an array. If the offset is larger than the size of the array, the result is an empty array rather than an error or false. A zero length, or a negative length that cuts away everything after the offset, also produces an empty array. The only way to trigger an error is to pass wrong types, such as a non-array for $array, which throws a TypeError.
Example 1: offsets and lengths
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$letters = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_slice($letters, 2), $flags), "\n";
echo json_encode(array_slice($letters, -2, 1), $flags), "\n";
echo json_encode(array_slice($letters, 1, -1), $flags), "\n";
echo json_encode(array_slice($letters, 10), $flags), "\n";["c","d","e"] ["d"] ["b","c","d"] []
The four calls take everything from position 2, one element starting two from the end, everything except the first and last element, and an offset past the end, which yields an empty array.
Example 2: what happens to keys
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$letters = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_slice($letters, 2, -1), $flags), "\n";
echo json_encode(array_slice($letters, 2, -1, true), $flags), "\n";
$fruits = ['a' => 'apple', 'b' => 'banana', '42' => 'pear', 'd' => 'orange'];
echo json_encode(array_slice($fruits, 0, 3), $flags), "\n";
echo json_encode(array_slice($fruits, 0, 3, true), $flags), "\n";["c","d"]
{"2":"c","3":"d"}
{"a":"apple","b":"banana","0":"pear"}
{"a":"apple","b":"banana","42":"pear"}
By default the numeric keys restart at 0. With preserve_keys set to true the slice keeps keys 2 and 3, so it is no longer a list and JSON encodes it as an object. In the fruit array the string keys survive both times, but the integer key 42 is renumbered to 0 unless you ask to preserve it.
Example 3: a pagination helper
function page(array $items, int $page, int $perPage): array
{
return array_slice($items, ($page - 1) * $perPage, $perPage);
}
$items = ['A', 'B', 'C', 'D', 'E'];
echo json_encode(page($items, 1, 2)), "\n";
echo json_encode(page($items, 3, 2)), "\n";
echo json_encode(page($items, 4, 2)), "\n";["A","B"] ["E"] []
The last page may be shorter than the page size, and a page beyond the data is simply empty, so no extra bounds checks are needed.
Edge cases
- A negative offset larger than the array size starts at the beginning instead of failing.
- An empty input array always gives an empty result.
- The offset counts positions, so in an array such as
[1 => 'a', 2 => 'b', 3 => 'c'], offset1selects'b', not the element with key1. - To keep the default length but still preserve keys, pass
nullexplicitly:array_slice($a, 2, null, true). Named arguments also work:array_slice($a, 2, preserve_keys: true). - The slice is a copy of the selected values. Changing it does not alter the original array.
Common mistakes
- Expecting keys to stay the same. After slicing a list that has numeric keys, the keys are renumbered unless
preserve_keysis true. This matters when the keys are database IDs or other identifiers. - Confusing length with an end position. The third argument is a count, not an index. Taking elements 2 through 4 is
array_slice($a, 2, 3), notarray_slice($a, 2, 4). - Forgetting that negative length trims from the end.
array_slice($a, 1, -1)removes the last element, it does not mean "one element backwards". - Using it to remove items.
array_slice()does not modify its input. To delete or replace a portion of an array in place, usearray_splice(). - Assuming
falseon a bad offset. An out-of-range offset returns[], so test withcount()or=== [], not with a false check.
Related functions
array_splice()removes a portion and can insert replacements, changing the original array.array_chunk()splits an entire array into several equal-sized pieces.unset()removes a single element by key.
Recap
array_slice($array, $offset, $length, $preserve_keys) copies a run of elements. Offsets and lengths may be negative to measure from the end, an offset past the end gives an empty array, string keys are always kept, and integer keys are renumbered unless you pass true as the fourth argument.
Tested examples
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$letters = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_slice($letters, 2), $flags), "\n";
echo json_encode(array_slice($letters, -2, 1), $flags), "\n";
echo json_encode(array_slice($letters, 1, -1), $flags), "\n";
echo json_encode(array_slice($letters, 10), $flags), "\n";
["c","d","e"] ["d"] ["b","c","d"] []
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$letters = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_slice($letters, 2, -1), $flags), "\n";
echo json_encode(array_slice($letters, 2, -1, true), $flags), "\n";
$fruits = ['a' => 'apple', 'b' => 'banana', '42' => 'pear', 'd' => 'orange'];
echo json_encode(array_slice($fruits, 0, 3), $flags), "\n";
echo json_encode(array_slice($fruits, 0, 3, true), $flags), "\n";
["c","d"]
{"2":"c","3":"d"}
{"a":"apple","b":"banana","0":"pear"}
{"a":"apple","b":"banana","42":"pear"}
function page(array $items, int $page, int $perPage): array
{
return array_slice($items, ($page - 1) * $perPage, $perPage);
}
$items = ['A', 'B', 'C', 'D', 'E'];
echo json_encode(page($items, 1, 2)), "\n";
echo json_encode(page($items, 3, 2)), "\n";
echo json_encode(page($items, 4, 2)), "\n";
["A","B"] ["E"] []