array_reduce

Reduces an array to a single value by running a callback that accumulates a carry across elements.

Signature
array_reduce(array $array, callable $callback, mixed $initial = null): mixed
  • Added in PHP 4.0.5

Parameters

ParameterTypeDescription
$arrayarrayThe array to reduce. Its keys are ignored.
$callbackcallableCalled as callback(mixed $carry, mixed $item): mixed. $carry is the previous return value (or $initial on the first call) and $item is the current value.
$initialoptionalmixed= nullThe starting value for the carry, and the result when the array is empty.

Return value

mixedThe final accumulated value. Returns initial if the array is empty, which is null when initial was not supplied.

Errors

Throws a TypeError if the callback is not callable; exceptions thrown inside the callback propagate out and abort the reduction.

Changelog

  • PHP 8.0.0If the callback expects a parameter by reference, an E_WARNING is emitted.

array_reduce() folds an array down to one value. The callback receives the running result ($carry) and the current element, and whatever it returns becomes the next $carry.

Always pass an initial value

With no $initial, the carry starts as null — so the first callback call receives null, and an empty array reduces to null rather than to a sensible zero value. Passing the identity for your operation (0 for sums, 1 for products, '' for strings, [] for arrays) makes the callback simpler and the empty case correct.

When to reach for it

Reach for it when the result is a single value that depends on every element and no built-in function already does it: order totals with per-line quantities, finding the row with the maximum of some field, building a lookup keyed by ID, computing a compound rate. For plain addition or multiplication, array_sum() and array_product() are far faster because they avoid a PHP callback per element.

What trips people up

The callback never receives the key. If the reduction depends on keys, reduce over array_keys() and close over the array, or use a foreach loop — clarity usually wins there.

Also watch the $carry type. Returning nothing from a branch of the callback silently sets the carry to null and quietly poisons every later iteration.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Total an order from line items that each have a quantity and price
  • Find the row with the largest value of one field in a single pass
  • Build an ID-keyed lookup table from a list of records
  • Compound a series of percentage rates into one multiplier

Frequently asked questions

What is the difference between array_reduce and array_map?

array_map returns a new array of the same length with each element transformed; array_reduce returns one single value accumulated across all elements. Use map to reshape, reduce to aggregate.

Can array_reduce access the array keys?

No — the callback only receives the carry and the value. Reduce over array_keys() and close over the original array if you need keys, or just write a foreach loop.

Should I use array_reduce instead of array_sum?

No. array_sum and array_product run entirely in C and are much faster than a PHP callback per element. Reach for array_reduce only when the accumulation is something those built-ins cannot express.

More examples

Finding the maximum row

The carry holds the best row seen so far and the null check handles the first iteration. Output is 'Cy is 41'. Unlike max() on a column, this keeps the whole row so you still have the name.

Example · php
<?php
$people = [
    ['n' => 'Ada', 'a' => 36],
    ['n' => 'Bo',  'a' => 28],
    ['n' => 'Cy',  'a' => 41],
];
$oldest = array_reduce(
    $people,
    fn($c, $p) => $c === null || $p['a'] > $c['a'] ? $p : $c
);
echo $oldest['n'], ' is ', $oldest['a'], "\n";

Building a lookup table

Starting from an empty array, each iteration adds one key and returns the carry. The result is [7 => 'widget', 12 => 'gadget']. Forgetting the return statement here is the classic bug — the carry would become null on the first pass.

Example · php
<?php
$rows = [
    ['id' => 7,  'name' => 'widget'],
    ['id' => 12, 'name' => 'gadget'],
];
$byId = array_reduce($rows, function (array $c, array $r): array {
    $c[$r['id']] = $r['name'];
    return $c;
}, []);
print_r($byId);
echo $byId[12], "\n";

The empty-array case

The first call returns NULL because no initial was given. The second returns int(0) and the third int(1), which are the correct identities for addition and multiplication. Supplying the identity removes an entire class of null-handling code downstream.

Example · php
<?php
$empty = [];
var_dump(array_reduce($empty, fn($c, $i) => $c + $i));
var_dump(array_reduce($empty, fn($c, $i) => $c + $i, 0));
var_dump(array_reduce($empty, fn($c, $i) => $c * $i, 1));

Discussion

  • Be the first to comment on this lesson.