array_map($callback, $array) chama $callback em cada elemento de $array e retorna um novo array com os resultados. O callback vem primeiro, o array depois, e o array original continua inalterado.
fn($p) => $p * 1.2 é uma arrow function: uma função de uma expressão que retorna o resultado. Qualquer callable funciona no lugar dela.
Usar uma função nativa como callback
Passe o nome de uma função nativa como string. É o jeito mais curto de limpar um array inteiro: aplicar trim em cada valor, converter strings em inteiros ou mudar maiúsculas e minúsculas.
array_map('intval', ...) é o jeito comum de transformar as strings de um formulário ou do explode() em inteiros de verdade. Você também pode escrever intval(...), a sintaxe de callable de primeira classe do PHP 8.1, que o seu editor consegue completar e verificar.
Usar uma closure com variáveis de fora
Uma arrow function enxerga automaticamente as variáveis em volta dela. Uma function clássica precisa de use para trazê-las. As duas são explicadas na página sobre funções anônimas.
array_map com chaves
Com um único array, o array_map mantém as chaves, incluindo chaves string. Mas o callback só recebe o valor. Para obter a chave também, passe array_keys($array) como segundo array: o callback é então chamado com um elemento de cada array.
Repare no segundo resultado: assim que você passa mais de um array, as chaves são substituídas por 0, 1, 2. É por isso que a última linha usa array_combine() para reconstruí-las.
Mapear vários arrays de uma vez
Cada array extra vira um argumento extra do callback, emparelhado pela posição. Se os arrays tiverem tamanhos diferentes, os mais curtos são completados com null.
Passar null como callback pula a função e junta os arrays em pares:
array_map, array_walk ou foreach
O array_map monta um novo array. O array_walk altera o array que você passa, por referência, e entrega a chave como segundo argumento do callback. Um foreach faz qualquer um dos dois e também pode pular elementos ou parar cedo com break.
Use array_map quando cada elemento vira exatamente um novo elemento. Se você também precisa descartar alguns elementos, combine com o array_filter, ou escreva um foreach.
Erro comum: a ordem dos argumentos
O array_map recebe o callback primeiro e o array depois. O vizinho dele, array_filter, recebe na ordem inversa, o que é fácil de confundir:
array_map($callback, $array); // callback first
array_filter($array, $callback); // array first
Trocar os dois faz o PHP 8 lançar um TypeError, porque um array simples não é um callback válido:
O PHP para com:
PHP Fatal error: Uncaught TypeError: array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members in /home/index.php:4
Troque os dois argumentos de volta e o bloco roda.
Perguntas frequentes
O que faz o array_map no PHP?
Ele chama uma função em cada elemento de um array e retorna um novo array com os resultados: array_map(fn($n) => $n * 2, [1, 2, 3]) retorna [2, 4, 6]. O array original não é alterado.
O array_map mantém as chaves?
Com um array, sim: chaves string e inteiras são mantidas como estão. Com dois ou mais arrays, o resultado sempre recebe novas chaves 0, 1, 2....
Como obtenho a chave dentro do callback do array_map?
Passe as chaves como um segundo array: array_map(fn($k, $v) => "$k=$v", array_keys($arr), $arr). O resultado é uma lista, então envolva em array_combine(array_keys($arr), ...) se precisar das chaves originais de volta.
O array_map é mais rápido que o foreach?
Não de forma relevante. Os dois percorrem o array uma vez, e um foreach simples muitas vezes é um pouco mais rápido, porque evita uma chamada de função por elemento. Escolha array_map quando ele for mais legível: uma transformação que produz um novo array.
Qual a diferença entre array_map e array_walk?
O array_map retorna um novo array e não mexe na entrada. O array_walk retorna true e serve para alterar o array no lugar por meio de um parâmetro por referência: array_walk($arr, function (&$v, $k) { $v = trim($v); });.