Menu

Funzioni anonime e closure in PHP: la parola chiave use

Una funzione anonima (closure) è una funzione senza nome salvata in una variabile: $greet = function ($name) { return "Hi $name"; };. Impara la parola chiave use, la cattura per riferimento, i callable, la sintassi first-class callable strlen(...) e le closure dentro le classi.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Una funzione anonima, chiamata anche closure, è una funzione senza nome. Scrivi function ($param) { ... } dove è atteso un valore: assegnala a una variabile, passala a un'altra funzione o restituiscila. Può portare con sé variabili del codice circostante con use ($var).

Ogni funzione anonima è un oggetto della classe predefinita Closure, ed è per questo che si può salvare, passare in giro e chiamare più tardi con $greet(...).

La parola chiave use cattura per valore

Una closure non può vedere da sola le variabili esterne. use ($x) copia il valore di $x nella closure nel momento in cui la closure viene creata, non quando viene eseguita:

use per riferimento: &$var

use (&$x) dà alla closure la variabile stessa invece di una copia. Le modifiche fatte dentro la closure sono visibili fuori, e quelle fatte fuori vengono viste dentro. È così che una callback aggiunge a un totale o tiene un contatore.

Ogni chiamata a makeCounter() crea un nuovo $count, e la closure restituita lo mantiene in vita dopo che la funzione è terminata. È a questo che si riferisce "closure": la funzione si chiude sulle variabili di cui ha bisogno.

Passare una closure come callback

Funzioni come array_map(), array_filter(), usort() e array_walk() accettano una funzione come argomento. Una closure ti permette di scriverla sul posto, con tutte le istruzioni che il lavoro richiede:

Quando il corpo è una singola espressione, una arrow function come fn($p) => $p['price'] è più breve e non richiede use.

Callable: nomi di funzione, metodi e strlen(...)

Un parametro con tipo callable accetta più delle closure. Valgono una stringa con il nome di una funzione, un array con un oggetto e il nome di un metodo, e un array con il nome di una classe e il nome di un metodo statico. Da PHP 8.1, la sintassi first-class callable strlen(...) trasforma direttamente ciascuno di questi in una Closure.

La forma (...) viene verificata quando la riga viene eseguita: un errore di battitura lancia subito un Error. Una stringa come 'strtoupr' resta solo una stringa finché qualcuno non prova a chiamarla.

Closure dentro una classe: $this e static

Una closure creata dentro un metodo ha $this collegato automaticamente, quindi può usare le proprietà dell'oggetto. Dichiarala static function quando non le serve $this, il che le impedisce anche di tenere in vita l'oggetto.

Dimenticare use

Il bug più comune con le closure è usare una variabile esterna senza elencarla in use. Dentro la closure la variabile non esiste:

$minAge = 18;
$adults = array_filter($people, function ($p) {
    return $p['age'] >= $minAge;   // $minAge is not in use (...)
});
PHP prints: Warning: Undefined variable $minAge

$minAge dentro è null, ogni età confrontata con >= null è true, e ogni persona supera il filtro. Su un server che nasconde i warning, nulla te lo segnala. Aggiungi la variabile a use:

Domande frequenti

Cos'è una closure in PHP?

Una funzione senza nome, creata con function (...) { ... } e salvata in una variabile o passata come argomento. PHP la rappresenta come un oggetto della classe Closure. Può portare con sé variabili dello scope in cui è stata creata, elencate in use (...).

Cosa fa la parola chiave use in una closure PHP?

use ($x) copia la variabile esterna $x nella closure quando la closure viene creata. Le modifiche successive a $x fuori non vengono viste. Scrivi use (&$x) per condividere invece la variabile, così le modifiche valgono in entrambe le direzioni.

Cos'è un callable in PHP?

Qualsiasi cosa PHP possa chiamare: una closure, il nome di una funzione come stringa ('strtoupper'), un array [$object, 'method'] o [ClassName::class, 'staticMethod'], oppure un oggetto con __invoke(). Usa il tipo callable per accettarli tutti e is_callable() per verificarli.

Cosa significa strlen(...) in PHP?

È la sintassi first-class callable di PHP 8.1: strlen(...) crea una Closure dalla funzione senza chiamarla. Funziona anche per i metodi, $obj->method(...), e per i metodi statici, Foo::bar(...), e viene verificata quando la riga viene eseguita, a differenza di un nome in una stringa.

Serve un punto e virgola dopo una funzione anonima?

Sì, quando la assegni: $f = function () { ... }; è un'istruzione di assegnazione, quindi termina con ;. Ometterlo è un errore di parsing. Una closure passata direttamente come argomento non ha bisogno di un punto e virgola proprio.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA