Arrays7 min readExamples run on PHP 8.5.10

array_map()

Learn how array_map() applies a callback to every element of one or more arrays, how it treats keys, and which mistakes to avoid in PHP 8.4.

Signature

array_map(?callable $callback, array $array, array ...$arrays): array
Available since PHP 4.0.67.48.08.18.28.38.48.5All versions →

Purpose

array_map() transforms data. You hand it a callback and one or more arrays, and it returns a new array holding the callback's result for each element. The input arrays are never modified. It is the usual choice when every input element should produce exactly one output element, such as converting prices, formatting names or combining two parallel lists.

Signature

Parameters and defaults

  • $callback: any callable, such as a closure, an arrow function, a function name string or a method callable. It may also be null, which switches to a zip operation (see below). There is no default; you must always pass this argument.
  • $array: the first array to walk through. It is required.
  • ...$arrays: optional extra arrays. The callback is called with one element from each array at the same position, so the number of parameters the callback accepts should match the number of arrays you pass.

Return value and failures

The function returns an array of callback results. Key handling depends on how many arrays you pass:

  • With exactly one array, the keys are preserved, including string keys.
  • With two or more arrays, the result has sequential integer keys starting at 0.

If the callback needs more arguments than you supply arrays, PHP throws an ArgumentCountError. Passing something that is not callable (and not null) or a non-array argument raises a TypeError. Since PHP 8.0, a callback that expects a parameter by reference causes an E_WARNING, so do not rely on array_map() to modify elements in place.

Example 1: one array and key preservation

With a single input array, each result sits under the same key as its source element.

Example
<?php
$prices = ['apple' => 3, 'pear' => 5];
$doubled = array_map(fn(int $n): int => $n * 2, $prices);
echo json_encode($doubled, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
$list = array_map(fn(int $n): int => $n + 1, [10, 20, 30]);
echo json_encode($list, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"apple":6,"pear":10}
[11,21,31]

Example 2: several arrays of different length

When arrays have unequal lengths, the shorter ones are extended with null values so the callback still receives a full set of arguments. The callback should therefore accept nullable parameters. Notice that the string keys of $names are discarded because two arrays were passed.

Example
<?php
$names = ['a' => 'Ann', 'b' => 'Bob', 'c' => 'Cy'];
$scores = [90, 80];
$result = array_map(
    fn(string $name, ?int $score): string => $name . ':' . ($score ?? 'none'),
    $names,
    $scores
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["Ann:90","Bob:80","Cy:none"]

Example 3: zipping and using keys

Passing null as the callback builds an array of groups, where each group contains the elements found at the same position in the input arrays. The callback also never receives array keys automatically. To use them, pass array_keys() and array_values() as two parallel arrays.

Example
<?php
$letters = ['x', 'y', 'z'];
$numbers = [1, 2, 3];
echo json_encode(array_map(null, $letters, $numbers), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
$arr = ['v1' => 'First', 'v2' => 'Second'];
$labels = array_map(fn(string $k, string $v): string => "$k=$v", array_keys($arr), array_values($arr));
echo json_encode($labels, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[["x",1],["y",2],["z",3]]
["v1=First","v2=Second"]

Edge cases

  • An empty input array produces an empty array, and the callback is never called.
  • array_map(null, $array) with a single array simply returns that array unchanged.
  • With several arrays and a null callback, string keys are lost and the groups are numbered from 0.
  • A callback that returns an array does not flatten anything; you get an array of arrays.
  • Extra arrays beyond what the callback accepts are ignored by the callback, but they still influence the result length, because the longest array decides how many calls happen.

Common mistakes

  1. Expecting keys to survive with multiple arrays. Only the single-array form preserves keys. If you need them, rebuild the result with array_combine() or use array_keys() as shown above.
  2. Using it only for side effects. array_map() builds and returns a new array. If you just want to run code for each element, a foreach loop or array_walk() is clearer.
  3. Forgetting nullable parameters. With unequal array lengths, a callback typed as int $score will fail when it receives the padded null.
  4. Mismatched argument counts. A callback requiring two parameters with only one array leads to an ArgumentCountError.
  5. Trying to modify by reference. The callback receives values, not references to the original elements, and a by-reference parameter triggers a warning.
  6. Using it to filter. The result always has one entry per input position. Use array_filter() when elements should be dropped.
  • array_filter() keeps only elements for which a callback returns a truthy value.
  • array_reduce() folds an array into a single value.
  • array_walk() applies a function to each element, optionally by reference, and returns a boolean.
  • array_keys() and array_values() help when you need keys as callback input.
  • array_combine() rebuilds an associative array from a list of keys and a list of values.

Recap

array_map() returns a new array with the callback applied to each element. One array keeps its keys; several arrays give a zero-based list and are padded with null when shorter. Use a null callback to zip arrays, match the callback's parameter count to the number of arrays, and choose another function when you want to filter, reduce or modify in place.

Tested examples

One array keeps its keys
<?php
$prices = ['apple' => 3, 'pear' => 5];
$doubled = array_map(fn(int $n): int => $n * 2, $prices);
echo json_encode($doubled, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
$list = array_map(fn(int $n): int => $n + 1, [10, 20, 30]);
echo json_encode($list, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"apple":6,"pear":10}
[11,21,31]
Several arrays of different length
<?php
$names = ['a' => 'Ann', 'b' => 'Bob', 'c' => 'Cy'];
$scores = [90, 80];
$result = array_map(
    fn(string $name, ?int $score): string => $name . ':' . ($score ?? 'none'),
    $names,
    $scores
);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["Ann:90","Bob:80","Cy:none"]
Zipping with null and using keys
<?php
$letters = ['x', 'y', 'z'];
$numbers = [1, 2, 3];
echo json_encode(array_map(null, $letters, $numbers), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
$arr = ['v1' => 'First', 'v2' => 'Second'];
$labels = array_map(fn(string $k, string $v): string => "$k=$v", array_keys($arr), array_values($arr));
echo json_encode($labels, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
[["x",1],["y",2],["z",3]]
["v1=First","v2=Second"]