callable
Aprenda o type hint callable do PHP — formas de callback, is_callable(), closures, __invoke e armadilhas comuns.
O Type Hint callable do PHP
Um callback é qualquer valor que o PHP pode invocar como se fosse uma função — um nome de função simples, um método em um objeto, uma closure, entre outros. O type hint callable permite declarar que um parâmetro, propriedade ou valor de retorno deve ser um desses valores invocáveis. Combinado com uma chamada real posteriormente ($callback(...)), é a base de funções de ordem superior como array_map(), usort() e array_filter().
Esta página aborda a sintaxe, todas as formas que um callable pode assumir, como validar um em tempo de execução com is_callable(), e as armadilhas que costumam pegar as pessoas de surpresa.
Sintaxe
Adicione callable antes do nome do parâmetro (ou como tipo de propriedade/retorno) para exigir um valor invocável:
<?php
function run(callable $callback) {
// $callback is guaranteed to be invocable here
return $callback();
}Se o chamador passar algo que não é callable, o PHP lança um TypeError antes de o corpo da sua função executar — portanto, dentro da função você pode confiar que $callback() funcionará.
As cinco formas de um callable
callable aceita mais do que apenas um nome de função. Cada linha abaixo é um valor diferente que o PHP reconhece como callback.
| Forma | Valor de exemplo | Chama |
|---|---|---|
| Nome de função (string) | 'strtoupper' | uma função nomeada |
| Método estático (string) | 'MyClass::myMethod' | um método estático |
| Método estático (array) | ['MyClass', 'myMethod'] | um método estático |
| Método de instância (array) | [$object, 'myMethod'] | um método em $object |
| Closure / arrow fn | function () { ... } | uma função anônima |
| Objeto invocável | $obj com __invoke() | o __invoke() do objeto |
O exemplo abaixo exercita todos eles com um único helper run():
<?php
function run(callable $callback): string
{
return $callback();
}
// 1. A named function passed by string
function greet(): string
{
return "Hello world!";
}
echo run('greet') . PHP_EOL;
// 2 & 3. Instance method and static method
class Greeter
{
public function instanceHello(): string
{
return "Hello from an instance";
}
public static function staticHello(): string
{
return "Hello from a static method";
}
}
$greeter = new Greeter();
echo run([$greeter, 'instanceHello']) . PHP_EOL; // instance method
echo run(['Greeter', 'staticHello']) . PHP_EOL; // static method
echo run('Greeter::staticHello') . PHP_EOL; // static method as a string
// 4. A closure (anonymous function)
echo run(function (): string {
return "Hello from a closure";
}) . PHP_EOL;
// 5. An invokable object (has an __invoke method)
class Loud
{
public function __invoke(): string
{
return "HELLO FROM __INVOKE";
}
}
echo run(new Loud()) . PHP_EOL;Executar isso imprime:
Hello world!
Hello from an instance
Hello from a static method
Hello from a static method
Hello from a closure
HELLO FROM __INVOKEVerificando um valor com is_callable()
Um type hint valida a entrada na fronteira da função, mas às vezes você recebe um valor dinamicamente (de configuração, entrada do usuário ou um registro) e quer verificá-lo antes de chamar. Use is_callable():
<?php
$maybe = 'strtoupper';
if (is_callable($maybe)) {
echo $maybe('hi'), PHP_EOL; // HI
} else {
echo "Not callable", PHP_EOL;
}
var_dump(is_callable('strtoupper')); // bool(true)
var_dump(is_callable('no_such_function')); // bool(false)
var_dump(is_callable([new DateTime(), 'format'])); // bool(true)is_callable() retorna true somente se o alvo realmente existe e é acessível — um nome de função com erro de digitação retorna false em vez de causar uma falha, o que o torna ideal para código no estilo plugin.
Sintaxe callable de primeira classe (PHP 8.1+)
Desde o PHP 8.1 você pode transformar qualquer função ou método em uma Closure com a sintaxe (...). Isso é type-safe, amigável para IDEs, e evita strings frágeis:
<?php
$upper = strtoupper(...); // a Closure wrapping strtoupper
echo $upper('hello'), PHP_EOL; // HELLO
$greeter = new DateTime('2020-01-01');
$fmt = $greeter->format(...); // bound to $greeter
echo $fmt('Y'), PHP_EOL; // 2020Como o resultado é uma Closure, ele satisfaz o type hint callable em qualquer lugar onde um callback é esperado.
Armadilhas comuns
- Métodos privados/protegidos. Um callable
[$object, 'method']só funciona se o método for visível a partir do local onde é invocado. Chamar um método privado via string/array de fora de sua classe falha. callablenão pode ser um tipo de propriedade antes do PHP 8.2 com ressalvas. Usarcallablecomo tipo de propriedade de classe não é permitido; armazene umaClosure(ou\Closure) em vez disso, ou aceite-o como parâmetro.- Chamada estática sem objeto.
[$object, 'staticMethod']funciona, mas por clareza prefira['ClassName', 'staticMethod']ou'ClassName::staticMethod'para alvos estáticos. Veja métodos estáticos. - Strings vs. objetos. Um callable de string como
'Greeter::staticHello'só funciona para métodos estáticos, não para métodos de instância — chamadas de instância precisam da forma de array[$object, 'method'].
Por que usar callable?
- Segurança de tipos: o PHP rejeita callbacks inválidos no ponto de chamada com um
TypeErrorclaro em vez de falhar dentro da sua função. - Assinaturas autodocumentadas: leitores (e ferramentas como PHPStan ou Psalm) veem imediatamente que um parâmetro é "algo que vou chamar".
- Flexibilidade: a mesma função aceita um nome de função, um método ou uma closure — assim os chamadores escolhem a forma mais conveniente.
Veja também
- Funções de callback PHP — usando callables com
array_map,usorte similares. - Funções PHP — definindo as funções que você passa como callbacks.
- Métodos estáticos PHP — as formas de callable para métodos estáticos.
- Tipos de dados PHP — onde
callablese encaixa entre os tipos do PHP.