callable
Impara il type hint callable in PHP — forme di callback, is_callable(), closure e __invoke con esempi pratici.
Il Type Hint callable in PHP
Un callback è qualsiasi valore che PHP può invocare come se fosse una funzione — un nome di funzione semplice, un metodo su un oggetto, una closure e così via. Il type hint callable ti permette di dichiarare che un parametro, una proprietà o un valore di ritorno deve essere uno di questi valori invocabili. Combinato con una chiamata reale in seguito ($callback(...)), costituisce la base delle funzioni di ordine superiore come array_map(), usort() e array_filter().
Questa pagina tratta la sintassi, ogni forma che un callable può assumere, come validarne uno a runtime con is_callable() e le insidie più comuni.
Sintassi
Aggiungi callable prima del nome del parametro (o come tipo di proprietà/ritorno) per richiedere un valore invocabile:
<?php
function run(callable $callback) {
// $callback is guaranteed to be invocable here
return $callback();
}Se il chiamante passa qualcosa che non è callable, PHP lancia un TypeError prima che il corpo della funzione venga eseguito — quindi all'interno della funzione puoi fare affidamento sul fatto che $callback() funzioni.
Le cinque forme di un callable
callable accetta più di un semplice nome di funzione. Ogni riga qui sotto è un valore diverso che PHP riconosce come callback.
| Forma | Valore di esempio | Chiama |
|---|---|---|
| Nome di funzione (string) | 'strtoupper' | una funzione con nome |
| Metodo statico (string) | 'MyClass::myMethod' | un metodo statico |
| Metodo statico (array) | ['MyClass', 'myMethod'] | un metodo statico |
| Metodo di istanza (array) | [$object, 'myMethod'] | un metodo su $object |
| Closure / arrow fn | function () { ... } | una funzione anonima |
| Oggetto invocabile | $obj con __invoke() | il metodo __invoke() dell'oggetto |
L'esempio qui sotto le esercita tutte con un unico 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;L'esecuzione stampa:
Hello world!
Hello from an instance
Hello from a static method
Hello from a static method
Hello from a closure
HELLO FROM __INVOKEVerificare un valore con is_callable()
Un type hint valida l'input al confine della funzione, ma a volte si riceve un valore dinamicamente (da configurazione, input utente o un registro) e si vuole verificarlo prima di chiamarlo. Usa 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() restituisce true solo se il target esiste effettivamente ed è raggiungibile — un nome di funzione scritto male restituisce false invece di andare in crash, il che lo rende ideale per codice di tipo plugin.
Sintassi callable di prima classe (PHP 8.1+)
Da PHP 8.1 puoi trasformare qualsiasi funzione o metodo in una Closure con la sintassi (...). Questo è type-safe, compatibile con i tool IDE, e evita stringhe fragili:
<?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; // 2020Poiché il risultato è una Closure, soddisfa il type hint callable ovunque ci si aspetti un callback.
Insidie comuni
- Metodi privati/protetti. Un callable
[$object, 'method']funziona solo se il metodo è visibile da dove viene invocato. Chiamare un metodo privato tramite stringa/array dall'esterno della sua classe fallisce. callablenon può essere un tipo di proprietà prima di PHP 8.2 con avvertenze. L'uso dicallablecome tipo di proprietà di classe non è consentito; usa invece unaClosure(o\Closure), oppure accettala come parametro.- Chiamata statica senza oggetto.
[$object, 'staticMethod']funziona, ma per chiarezza preferisci['ClassName', 'staticMethod']o'ClassName::staticMethod'per i target statici. Vedi metodi statici. - Stringhe vs. oggetti. Un callable stringa come
'Greeter::staticHello'funziona solo per i metodi statici, non per quelli di istanza — le chiamate di istanza richiedono la forma array[$object, 'method'].
Perché usare callable?
- Type safety: PHP rifiuta i callback non validi al sito di chiamata con un chiaro
TypeErrorinvece di fallire in profondità all'interno della funzione. - Firme auto-documentanti: i lettori (e strumenti come PHPStan o Psalm) vedono immediatamente che un parametro è "qualcosa che chiamerò."
- Flessibilità: la stessa funzione accetta un nome di funzione, un metodo o una closure — così i chiamanti scelgono la forma più comoda.
Vedi anche
- Funzioni callback PHP — utilizzo dei callable con
array_map,usorte simili. - Funzioni PHP — definire le funzioni da passare come callback.
- Metodi statici PHP — le forme callable dei metodi statici.
- Tipi di dati PHP — dove
callablesi inserisce tra i tipi PHP.