Signature
array_chunk(array $array, int $length, bool $preserve_keys = false): arrayPurpose
array_chunk() takes one array and cuts it into a list of smaller arrays, each holding a fixed number of elements. It is useful whenever you need to work in groups: sending records to an API in batches, laying out items in rows of three, or processing a long list a few entries at a time. The original array is not modified; you receive a new array of chunks.
Signature
Parameters and defaults
$arrayis the input array. It may be a list or an associative array, and its elements can be of any type.$lengthis the size of each chunk. It must be at least 1. Every chunk has exactly this many elements, except possibly the last one, which holds whatever is left over.$preserve_keysdefaults tofalse. With the default, each chunk is reindexed from0, so string keys and original integer keys are discarded. When you passtrue, the original keys are kept inside each chunk.
Return value and failure cases
The function returns a numerically indexed array that starts at zero. Each element of that array is itself an array, one per chunk. The order of the elements is the same as in the input.
If $length is less than 1, PHP throws a ValueError. This has been the behavior since PHP 8.0; you do not get a warning or a null return value any more. Passing an empty array is not an error: the result is simply an empty array, because there are no chunks to build.
Example 1: batching a list
The simplest use is splitting a flat list. With five items and a length of two, you get two full chunks and one chunk with the single leftover element.
$items = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_chunk($items, 2), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[["a","b"],["c","d"],["e"]]
The result is a list of three arrays. Notice that the last chunk is shorter. If your code assumes every chunk is full, for example when it reads a fixed index, it needs to handle this case.
Example 2: keys with and without preserve_keys
By default the keys of an associative array are lost. That surprises many people, because the values survive but their labels do not. Set the third argument to true when the keys matter.
$stock = ['apple' => 3, 'pear' => 5, 'plum' => 8];
echo json_encode(array_chunk($stock, 2), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_chunk($stock, 2, true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[[3,5],[8]]
[{"apple":3,"pear":5},{"plum":8}]
The first line shows plain lists of values. The second shows each chunk as an object-like map, because the string keys are still present. The outer array is always a plain list, whatever you pass for $preserve_keys.
Example 3: errors and boundary inputs
A length below 1 is rejected, an empty array gives an empty result, and a length larger than the array gives a single chunk containing everything.
try {
array_chunk([1, 2, 3], 0);
} catch (ValueError $e) {
echo get_class($e), "\n";
}
echo json_encode(array_chunk([], 3)), "\n";
echo json_encode(array_chunk([1, 2, 3], 10)), "\n";ValueError [] [[1,2,3]]
These boundaries are worth knowing when the length comes from user input or configuration. Validate it before the call, or catch the exception where the value enters your program.
Edge cases
- Leftover chunk: the final chunk can be smaller than
$length. If you need equal sizes, pad the input first or handle the short chunk explicitly. - Length of 1: every element becomes its own one-element array, which is a quick way to wrap each value.
- Preserved numeric keys: with
true, a chunk taken from the middle of a list keeps keys such as2and3, not0and1. Code that expects index0in each chunk will break. - Nested values: elements are copied as they are. Nested arrays are not split further.
Common mistakes
- Expecting string keys to survive without passing
trueas the third argument. - Passing the arguments in the wrong order. The array comes first and the size second, which is the opposite of what some other languages use.
- Calculating the length from a count that can be zero, for example dividing a total by a number of columns, and then hitting a
ValueError. - Assuming the number of chunks equals the length. The length is the size of each chunk, not how many chunks you get. To get a fixed number of chunks, compute the size with
ceil(count($array) / $parts)after making sure the result is at least 1. - Forgetting that the function returns a new array and ignoring the return value.
Related functions
array_slice()extracts one portion of an array by offset and length, which is useful when you only need a single group.array_splice()removes or replaces a portion in place.array_combine()andarray_map()often pair well with chunks when you transform each group.
Recap
array_chunk($array, $length, $preserve_keys) returns a list of arrays of up to $length elements each. The last chunk may be shorter, keys are reindexed unless you ask to preserve them, an empty array yields an empty result, and a length below 1 throws a ValueError.
Tested examples
$items = ['a', 'b', 'c', 'd', 'e'];
echo json_encode(array_chunk($items, 2), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[["a","b"],["c","d"],["e"]]
$stock = ['apple' => 3, 'pear' => 5, 'plum' => 8];
echo json_encode(array_chunk($stock, 2), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_chunk($stock, 2, true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[[3,5],[8]]
[{"apple":3,"pear":5},{"plum":8}]
try {
array_chunk([1, 2, 3], 0);
} catch (ValueError $e) {
echo get_class($e), "\n";
}
echo json_encode(array_chunk([], 3)), "\n";
echo json_encode(array_chunk([1, 2, 3], 10)), "\n";ValueError [] [[1,2,3]]