Dopo avere imparato ad utilizzare il metodo costruttore ed a personalizzare la fase di creazione delle istanze tramite la lezione precedente, è ora arrivato il momento di capire come e quando avviene la fase opposta, ovvero la distruzione degli oggetti.
Il metodo distruttore
Se il metodo magico __construct
viene richiamato quando si creano gli oggetti, il rispettivo metodo magico __destruct
viene richiamato nella fase di distruzione degli stessi. Prima di capire come avviene la distruzione degli oggetti, vediamo come è possibile dichiarare un distruttore all'interno di una classe:
class MyClass {
// proprietà
public $a = 10;
public $b = 20;
// costruttore
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
// connessione al database interno
connect_to_my_db($this->a, $this->b);
}
// distruttore
public function __destruct() {
// operazioni di clean up...
// chiusura del database e rilascio delle risorse
free_my_db();
}
// metodi
public function sayHello() {
echo "Hello! " . $this->a . " " . $this->b;
}
}
// creazione delle istanze
$myClass_1 = new MyClass("username", "password");
Come possiamo notare, la dichiarazione del metodo distruttore è assai simile a quella del metodo costruttore, tranne per il fatto che il primo non accetta argomenti.
Quando vengono eliminati gli oggetti
A differenza della fase di creazione degli oggetti, che è assolutamente esplicita, la fase di distruzione non lo è altrettanto. PHP infatti, chiama il metodo distruttore solo quando è davvero sicuro che tutti i riferimenti all'oggetto siano stati cancellati oppure quando l'oggetto è distrutto/cancellato manualmente (per cancellare un oggetto, o in via generale una variabile, è possibile richiamare la funzione unset oppure settare esplicitamente l'oggetto ad un nuovo valore). Ecco un esempio di distruzione di un oggetto molto semplice:
class MyClass {
// proprietà
public $a = 10;
public $b = 20;
// costruttore
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
// distruttore
public function __destruct() {
echo "__destruct method called!";
}
}
// creazione delle istanze
$myClass_1 = new MyClass("username", "password");
$myClass_2 = new MyClass("username", "password");
$myClass_3 = new MyClass("username", "password");
$myClass_4 = $myClass_3;
// distruzione delle istanze
unset($myClass_1); // stampa "__destruct method called"
$myClass_2 = 0; // stampa "__destruct method called"
unset($myClass_3); // non chiama il distruttore, esiste ancora un riferimento all'oggetto $myClass_3
Oltre alle situazioni elencate nel precedente paragrafo, occorre sapere che tutti gli oggetti, come del resto tutte le variabili, vengono distrutti automaticamente da PHP al termine dello script. Ciò significa che il metodo distruttore verrà sicuramente richiamato automaticamente al termine dell'esecuzione della nostra applicazione:
class MyClass {
// proprietà
public $a = 10;
public $b = 20;
// costruttore
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
// distruttore
public function __destruct() {
echo "__destruct method called!";
}
}
// creazione delle istanze
$myClass_1 = new MyClass("username", "password");
// stampa "__destruct method called" alla fine dello script
Conclusione
In questa lezione abbiamo potuto osservare la potenza e soprattutto l'utilità del metodo distruttore. Anche se quest'ultimo non verrà utilizzato spesso come il metodo costruttore, rappresenta sempre uno strumento dall'indubbia potenza: viene utilizzato in molti scenari reali, come ad esempio quando occorre chiudere la connessione ad un database, terminare l'handle ad un file o chiudere la connessione a risorse esterne. Insomma, si può affermare che generalmente il distruttore viene richiamato quando occorre effettuare il clean up delle risorse.