Programação Funcional em PHP: da teoria à prática
O PHP é tradicionalmente associado a abordagens imperativas e orientadas a objetos, no entanto, a linguagem moderna oferece ferramentas poderosas para programação funcional (FP). Neste artigo, vamos explorar como aplicar os princípios de FP em PHP: desde funções anônimas até currying e imutabilidade. Você aprenderá como tornar o código mais previsível, testável e conciso.
1. Fundamentos: funções anônimas e closures
Funções anônimas (lambdas) são a pedra angular da FP em PHP. Elas permitem passar comportamento como dados.
<?php// Função anônima simples$greet = function($name) { return "Olá, $name!";};echo $greet('Mundo'); // Olá, Mundo!
// Uso com array_map$numbers = [1, 2, 3, 4, 5];$squared = array_map(function($n) { return $n * $n;}, $numbers);print_r($squared); // [1, 4, 9, 16, 25]?>Closures são funções anônimas que capturam variáveis do escopo externo usando a palavra-chave use:
<?php$factor = 3;$multiply = function($n) use ($factor) { return $n * $factor;};echo $multiply(5); // 15
// Closure com variável mutável (por referência)$counter = 0;$increment = function() use (&$counter) { $counter++;};$increment();echo $counter; // 1?>Closures são indispensáveis na criação de funções callback e fábricas.
2. Funções de alta ordem: array_map, array_filter, array_reduce
O PHP possui funções clássicas de alta ordem que aceitam outras funções como argumentos:
array_map— transforma cada elemento do array;array_filter— filtra elementos com base em uma condição;array_reduce— reduz o array a um único valor.
<?php$data = [1, 2, 3, 4, 5, 6];
// Filtrar números pares$even = array_filter($data, function($n) { return $n % 2 === 0;}); // [2, 4, 6]
// Dobrar cada elemento$doubled = array_map(function($n) { return $n * 2;}, $even); // [4, 8, 12]
// Soma de todos os valores$sum = array_reduce($doubled, function($carry, $n) { return $carry + $n;}, 0); // 24?>Observe: array_filter preserva as chaves. Se precisar de reindexação, use array_values().
3. Imutabilidade e trabalho com dados
A programação funcional incentiva a imutabilidade — a imutabilidade dos dados. Em vez de modificar objetos existentes, novos são criados.
<?php// Abordagem imperativa (mutação)$user = ['name' => 'João', 'age' => 25];$user['age'] = 26; // modifica o array original
// Abordagem funcional (imutável)$user = ['name' => 'João', 'age' => 25];$updatedUser = array_merge($user, ['age' => 26]); // novo array?>Para trabalhar com arrays, use array_merge, array_slice e o operador spread (PHP 7.4+):
<?php$original = [1, 2, 3];$new = [...$original, 4]; // [1, 2, 3, 4] — o original não foi alterado?>A imutabilidade simplifica a depuração e torna o código thread-safe.
4. Currying e aplicação parcial
Currying é a transformação de uma função de vários argumentos em uma sequência de funções de um argumento. Aplicação parcial é a fixação de parte dos argumentos.
O PHP não possui currying nativo, mas é fácil de implementar:
<?php// Função de soma curriedfunction curryAdd($a) { return function($b) use ($a) { return function($c) use ($a, $b) { return $a + $b + $c; }; };}
$add5 = curryAdd(5);