Closures e funções anônimas
Nesta aula, exploramos closures e funções anônimas em PHP, cobrindo sua sintaxe, captura de variáveis com 'use', arrow functions e o tipo callable. Ao final, você será capaz de criar funções anônimas, entender seu escopo e utilizá-las em callbacks.
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
callablepara clareza.
Referências
- PHP: Funções anônimas
- PHP: Arrow Functions
- PHP: Callable
- PHP: Classe Closure
- PHP: is_callable
- PHP: array_map
- PHP: usort
Exercícios
-
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 -
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 -
Reescreva o exercício anterior usando arrow function.
✓ Resposta:
$fator = 3; $multiplicar = fn($n) => $n * $fator; echo $multiplicar(5); // 15 -
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 -
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