Arrays7 min readExamples run on PHP 8.5.10

array_slice()

Learn how array_slice() extracts part of an array in PHP 8.4, how offset, length and preserve_keys interact, and which mistakes to avoid.

Signature

array_slice(
    array $array,
    int $offset,
    ?int $length = null,
    bool $preserve_keys = false
): array

Purpose

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 -2 starts 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". With null (the default) the slice runs to the end of the array.
  • $preserve_keys: defaults to false. 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

Example
<?php
$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";
Output
["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

Example
<?php
$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";
Output
["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

Example
<?php
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";
Output
["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'], offset 1 selects 'b', not the element with key 1.
  • To keep the default length but still preserve keys, pass null explicitly: 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

  1. Expecting keys to stay the same. After slicing a list that has numeric keys, the keys are renumbered unless preserve_keys is true. This matters when the keys are database IDs or other identifiers.
  2. 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), not array_slice($a, 2, 4).
  3. Forgetting that negative length trims from the end. array_slice($a, 1, -1) removes the last element, it does not mean "one element backwards".
  4. Using it to remove items. array_slice() does not modify its input. To delete or replace a portion of an array in place, use array_splice().
  5. Assuming false on a bad offset. An out-of-range offset returns [], so test with count() or === [], not with a false check.
  • 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

Offsets and lengths
<?php
$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";
Output
["c","d","e"]
["d"]
["b","c","d"]
[]
What happens to keys
<?php
$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";
Output
["c","d"]
{"2":"c","3":"d"}
{"a":"apple","b":"banana","0":"pear"}
{"a":"apple","b":"banana","42":"pear"}
A pagination helper
<?php
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";
Output
["A","B"]
["E"]
[]