Programação Funcional em PHP: Nível Avançado
O PHP é tradicionalmente associado a estilos imperativos e orientados a objetos, no entanto, a linguagem moderna (especialmente a partir da versão 7.4) fornece ferramentas poderosas para aplicar o paradigma funcional. Neste artigo, exploraremos conceitos avançados de programação funcional (FP) em PHP que ajudarão a escrever código mais previsível, testável e expressivo.
1. Funções Puras e Imutabilidade de Dados
Na base da FP estão as funções puras — funções que:
- Dependem apenas de seus argumentos (não usam variáveis globais ou estado fora do escopo);
- Não causam efeitos colaterais (não alteram dados externos, não escrevem em arquivos, não enviam requisições HTTP);
- Para os mesmos dados de entrada, sempre retornam o mesmo resultado.
Em PHP, a imutabilidade de dados é ativamente usada para garantir a pureza das funções. Em vez de modificar arrays ou objetos existentes, são criadas cópias com as alterações.
<?php// Função impura (usa um array global)$globalData = [1, 2, 3];function addElementImpure($value) { global $globalData; $globalData[] = $value; // Efeito colateral return $globalData;}
// Função pura (retorna um novo array)function addElementPure(array $data, $value): array { $newData = $data; $newData[] = $value; return $newData;}
$original = [1, 2, 3];$modified = addElementPure($original, 4);// $original permanece [1, 2, 3], $modified = [1, 2, 3, 4]?>2. Closures e Captura de Variáveis
Closures em PHP são funções anônimas que podem capturar variáveis do escopo pai através da palavra-chave use. Esta é a base para criar funções de ordem superior.
É importante distinguir entre captura por valor (padrão) e por referência (&use). No contexto da FP, a captura por valor é preferível para não violar a pureza.
<?php$multiplier = 3;
// Closure capturando $multiplier por valor$multiply = function ($value) use ($multiplier) { return $value * $multiplier;};
echo $multiply(5); // 15
// Exemplo de função de ordem superior que retorna uma closurefunction createGreeter(string $greeting): Closure { return function (string $name) use ($greeting) { return "{$greeting}, {$name}!"; };}
$sayHello = createGreeter('Hello');echo $sayHello('World'); // Hello, World!?>3. Currying e Aplicação Parcial
Currying é a transformação de uma função que recebe vários argumentos em uma sequência de funções, cada uma recebendo um único argumento. Aplicação parcial é a fixação de parte dos argumentos para obter uma nova função com menos parâmetros.
O PHP não possui suporte nativo para currying, mas ele pode ser implementado usando closures.
<?php// Função normalfunction add(int $a, int $b, int $c): int { return $a + $b + $c;}
// Versão curried$curriedAdd = function (int $a) { return function (int $b) use ($a) { return function (int $c) use ($a, $b) { return $a + $b + $c; }; };};
echo $curriedAdd(1)(2)(3); // 6
// Aplicação parcial com função auxiliarfunction partial(callable $fn, ...$fixedArgs): Closure { return function (...$remainingArgs) use ($fn, $fixedArgs) { return $fn(...array_merge($fixedArgs, $remainingArgs)); };}
$addFive = partial('add', 2, 3);echo $addFive(10); // 15 (2 + 3 + 10)?>4. Composição de Funções e Pipelines
A composição de funções permite combinar várias funções simples em uma função complexa, passando o resul