English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Analisi approfondita di closure e funzioni anonime in PHP

Una closure è una funzione che chiude l'ambiente circostante. Anche se l'ambiente in cui si trova la closure non esiste più, lo stato encapsulato nella closure esiste ancora.

Una funzione anonima è una funzione senza nome. Le funzioni anonime possono essere assegnate a una variabile e possono essere trasmesse come qualsiasi altro oggetto PHP. Tuttavia, le funzioni anonime sono ancora funzioni e possono essere chiamate, accettando anche parametri. Le funzioni anonime sono particolarmente adatte come callback per funzioni o metodi.

Attenzione: Teoricamente parlando, le closure e le funzioni anonime sono concetti diversi. Tuttavia, PHP le considera come concetti identici. Pertanto, quando menzioniamo le closure, ci riferiamo anche alle funzioni anonime e viceversa.

La sintassi utilizzata per le closure in PHP e le funzioni anonime è la stessa delle funzioni comuni, ma le closure e le funzioni anonime sono in realtà oggetti mascherati come funzioni (esemplari della classe Closure).

Creazione di una closure

$closure = function($name){
  return sprintf("Hello %s", $name);
}
echo $closure("jerry");
// Verifica se la variabile $closure è una closure
var_dump($closure instanceof Closure);

Il codice sopra crea un oggetto closure e lo assegna alla variabile $closure. La closure è molto simile a una funzione PHP comune, utilizza la stessa sintassi, accetta parametri e può restituire un valore.

Spiegazione: Possiamo chiamare la variabile $closure perché il suo valore è una closure e l'oggetto closure ha implementato il metodo magico __invoke(). Se c'è una parentesi graffa dopo il nome della variabile, PHP cerca e chiama il metodo __invoke().

Usare il closure

Di solito usiamo i closure PHP come callback per funzioni e metodi. Molte funzioni PHP utilizzano callback, come array_map() e preg_replace_callback(). Nell'esempio seguente, utilizzeremo array_map() per elaborare un array, aumentando di 1 ogni elemento dell'array:

$nubmers = array_map(function($number){
  return $number++;
}, [1,2,3]);
var_dump($numbers);

Aggiungi stato

I closure PHP non si comportano come i closure JavaScript reali, che automaticamente encapsulano lo stato dell'applicazione. Dobbiamo manualmente chiamare il metodo bindTo() dell'oggetto closure o utilizzare la parola chiave use per aggiungere lo stato al closure PHP.

Usare la parola chiave use

L'uso della parola chiave use per aggiungere stato alla closure è più comune, quindi vediamo questo metodo prima. Quando si aggiungono variabili alla closure utilizzando la parola chiave use, le variabili ricordano il valore assegnato al momento dell'aggiunta.

function Car ($name){
  return function($statu)use($name){
    return sprintf("Car %s is %s", $name, $statu); 
  }
}
// Encapsula il nome dell'auto nel closure
$car = Car("bmw");
// Esegui l'azione dell'auto
// Output: "bmw is running"
echo $car("running");

Attenzione: puoi passare più parametri al closure utilizzando la parola chiave use, in questo caso, i parametri devono essere separati da virgola come i parametri di una funzione o un metodo PHP.

Aggiungi lo stato del closure utilizzando il metodo bindTo()

Similmente ad altri oggetti PHP, ogni istanza di closure può utilizzare la parola chiave $this per ottenere lo stato interno della closure. Lo stato predefinito dell'oggetto closure non è molto utile, ma ci sono il metodo magico __invoke() e il metodo bindTo().

Il metodo bindTo() aggiunge alcune potenzialità interessanti al closure. Possiamo utilizzare questo metodo per associare lo stato interno dell'oggetto Closure a un altro oggetto.

Il secondo parametro del metodo bindTo() è molto importante, il suo ruolo è specificare la classe PHP di appartenenza dell'oggetto al quale viene associato il closure. Pertanto, il closure può accedere alle variabili membro protette e private dell'oggetto al quale è associato.

class TestClosure
}
  private $name=[];
  private $age;
  private $sex;
  public function addPerson($name, $personCallback){
    // Binда oggetto closure all'istanza corrente
    $this->name[$name] = $personCallback->bindTo($this, __CLASS__);
  }
  public function display($name){
    foreach ($this->name as $key => $callback){
      if($key == $name){
        // Esegui l'oggetto closure, aggiungi lo stato della closure all'istanza della classe
        $callback();
      }
    }
    echo "name : {$name}\n";
    echo "age : {$this->age}\n";
    echo "sex : {$this->sex}\n";
  }
}
$person = new TestClosure();
$person->addPerson("jerry", function(){
  $this->age = 19;
  $this->sex = "man";
});
$person->display("jerry");
/** output
name : jerry
age : 19
sex : man
*/

Conclusione

Come menzionato sopra, questo è ciò che l'autore ha introdotto ai lettori su closure e funzioni anonime in PHP, sperando che sia utile a tutti. Se avete qualsiasi domanda, lasciate un commento e l'autore risponderà prontamente. In questo senso, l'autore desidera anche ringraziare tutti per il supporto al sito di tutorial Yelling!

Ti potrebbe interessare