Funções anônimas (closures) são funções sem nome que podem ser armazenadas em variáveis, passadas como argumentos ou retornadas por outras funções. Em PHP, elas são implementadas pela classe Closure e permitem capturar variáveis do escopo pai através da palavra-chave use. Arrow functions (fn) são uma sintaxe concisa para closures que automaticamente capturam variáveis por referência. O tipo callable é um pseudo-tipo que aceita funções (nomes ou closures) como argumentos, sendo amplamente utilizado em funções de ordenação, filtros e callbacks.

Funções anônimas

Uma função anônima é definida sem um nome e pode ser atribuída a uma variável ou passada diretamente como argumento. A sintaxe básica usa a palavra-chave function, seguida de parênteses para parâmetros e chaves para o corpo. Exemplo:

$saudacao = function($nome) {
    return "Olá, $nome!";
};
echo $saudacao('Maria'); // Olá, Maria!

Elas são úteis para callbacks, como em array_map ou usort. Note que, como qualquer função, podem ter parâmetros e retornar valores. A variável que armazena a closure é do tipo Closure, e pode ser invocada como qualquer função.

use (captura)

Por padrão, funções anônimas não têm acesso às variáveis do escopo onde foram definidas. Para capturar uma variável do escopo pai, usamos a cláusula use após a lista de parâmetros. Exemplo:

$mensagem = 'Bem-vindo';
$saudacao = function($nome) use ($mensagem) {
    return "$mensagem, $nome!";
};
echo $saudacao('João'); // Bem-vindo, João!

Variáveis capturadas por valor (use ($var)) são copiadas no momento da definição da closure. Para capturar por referência, use use (&$var), permitindo que a closure modifique a variável externa. Exemplo:

$contador = 0;
$incrementar = function() use (&$contador) {
    $contador++;
};
$incrementar();
echo $contador; // 1

Arrow functions (fn)

Arrow functions, introduzidas no PHP 7.4, são uma sintaxe reduzida para closures que automaticamente capturam variáveis do escopo pai por referência. A sintaxe é fn(argumentos) => expressão. Exemplo:

$multiplicador = 2;
$numeros = [1, 2, 3];
$resultado = array_map(fn($n) => $n * $multiplicador, $numeros);
print_r($resultado); // [2, 4, 6]

Arrow functions não podem ter múltiplas instruções; apenas uma expressão que é retornada automaticamente. Elas não suportam a cláusula use explícita, pois a captura é implícita e por referência. Também não podem modificar variáveis externas (apenas ler).

Callable

O tipo callable é um pseudo-tipo que representa qualquer função que possa ser chamada: nomes de funções (strings), métodos estáticos (arrays com classe e método), métodos de objeto (arrays com objeto e método) ou closures. Funções que aceitam callables incluem array_map, usort, call_user_func, etc. Exemplo:

function saudacao($nome) {
    return "Olá, $nome!";
}

$closure = function($nome) {
    return "Oi, $nome!";
};

$callables = ['saudacao', $closure];
foreach ($callables as $callable) {
    if (is_callable($callable)) {
        echo $callable('Ana') . "\n";
    }
}

Para verificar se algo é callable, use a função is_callable(). O tipo callable é amplamente utilizado em programação funcional e design patterns como Strategy.

Boas práticas

  • Prefira arrow functions para closures simples de uma expressão, pois são mais concisas.
  • Evite capturar muitas variáveis com use; considere passar como argumentos.
  • Use use (&$var) apenas quando necessário modificar a variável externa.
  • Documente callables com type hints callable para clareza.

Referências

Exercícios

  1. Crie uma função anônima que receba dois números e retorne a soma. Atribua a uma variável e execute.

    ✓ Resposta:
    $soma = function($a, $b) {
        return $a + $b;
    };
    echo $soma(3, 4); // 7
  2. Usando use, crie uma closure que multiplique um número por um fator definido fora da closure.

    ✓ Resposta:
    $fator = 3;
    $multiplicar = function($n) use ($fator) {
        return $n * $fator;
    };
    echo $multiplicar(5); // 15
  3. Reescreva o exercício anterior usando arrow function.

    ✓ Resposta:
    $fator = 3;
    $multiplicar = fn($n) => $n * $fator;
    echo $multiplicar(5); // 15
  4. Escreva uma função que aceite um callable e dois números, e execute o callable com esses números. Teste com uma closure que some.

    ✓ Resposta:
    function executar(callable $callback, $a, $b) {
        return $callback($a, $b);
    }
    
    $soma = fn($x, $y) => $x + $y;
    echo executar($soma, 10, 20); // 30
  5. Crie uma closure que incremente um contador externo por referência usando use. Chame-a três vezes e exiba o contador.

    ✓ Resposta:
    $contador = 0;
    $incrementar = function() use (&$contador) {
        $contador++;
    };
    $incrementar();
    $incrementar();
    $incrementar();
    echo $contador; // 3