Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 44 di 50
  • livello avanzato
Indice lezioni

I metodi magici - Seconda parte

La lista dei metodi magici. Seconda parte parte: sleep, wakeup, toString, set_state, invoke, clone
La lista dei metodi magici. Seconda parte parte: sleep, wakeup, toString, set_state, invoke, clone
Link copiato negli appunti

Continuiamo l'analisi dei rimanenti metodi magici, dopo quelli affrontati nella lezione precedente.

__sleep e __wakeup

Questi due metodi magici vengono richiamati rispettivamente in fase di serializzazione e deserializzazione degli oggetti. Il metodo __sleep deve restituire un array contenente i nomi delle proprietà da serializzare (altrimenti verrà generato un errore di tipo E_NOTICE) e si usa generalmente per operazioni di cleanup, mentre il metodo __wakeup svolge il compito opposto: può essere usato, ad esempio, per riaprire le connessioni ai database o alle risorse esterne.

class MyClass {
    protected $link;
    public $host, $username, $password, $db;
    public function __construct($host, $username, $password, $db)
    {
        $this->host = $host;
        $this->username = $username;
        $this->password = $password;
        $this->db = $db;
                // connessione al database
                $this->connect();
    }
    private function connect() {
                // connessione ad un database
        $this->link = mysql_connect($this->host, $this->username, $this->password);
        mysql_select_db($this->db, $this->link);
    }
    public function __sleep() {
        // serializzazione di 4 proprietà
                return array('host', 'username', 'password', 'db');
    }
        // ripristino della connessione al database
    public function __wakeup() {
        $this->connect();
    }
}
$obj1 = new MyClass('host', 'username', 'password', 'db');
$obj1_serialized = serialize($obj1);
// successivamente...
$obj2 = unserialize($obj1_serialized);
// stampa "host"
echo $obj2->host;

__toString

Il metodo magico __toString è molto utile. Se si stampasse un'istanza con le funzioni echo o print, si otterrebbe una stringa del tipo Object #... oppure un errore di tipo Catchable Fatal Error, perchè di default gli oggetti non sono dati stampabili con regole precise. Queste regole possiamo deciderle noi programmando cosa deve accadere quando viene stampata un'istanza:

class MyClass {
        public $a = 10;
        public $b = 20;
        public $c = 30;
        public function __toString() {
                $s = "Stai stampando un'istanza della classe " . get_class() . ".";
                $s .= "Ecco i valori delle sue proprietà: " . $this->a . "-" . $this->b . "-" . $this->c;
                return $s;
        }
}
$obj1 = new MyClass();
// Stai stampando un'istanza della classe MyClass.Ecco i valori delle sue proprietà: 10-20-30
echo $obj1;

__set_state e __invoke

Questi due metodi magici sono molto probabilmente i meno utilizzati tra tutti quelli disponibili. Il primo viene azionato quando si esporta un oggetto tramita la funzione var_export ed accetta un array che avrà le coppie key/value impostate ai nomi/valori delle proprietà esportate. Il secondo (disponibile a partire dalla versione 5.3.0) viene richiamato quando si usa un oggetto come una funzione.

// __set_state
class MyClass
{
    public $a;
    public $b;
    public static function __set_state($arr)
    {
        $obj = new MyClass;
        $obj->a = $arr['a'];
        $obj->b = $arr['b'];
        return $obj;
    }
}
$obj1 = new MyClass();
$obj1->a = 10;
$obj1->b = 20;
eval('$obj2 = ' . var_export($obj1, true) . ';');
// __invoke
class MyClass {
        public function __invoke($x) {
        echo $x;
    }
}
$obj1 = new MyClass();
$obj1(5);

__clone

Come abbiamo visto nella lezione dedicata alla clonazione degli oggetti, è possibile stabilire cosa deve accadere quando questa situazione si verifica. La parte interessante del metodo __clone è rappresentata dal fatto che al suo interno la pseudovariabile $this si riferisce all'istanza clonata, e quindi si ha l'immediata possibilità di compiere operazioni con essa:

class MyClass {
        public $a = 10;
        public $b = 20;
        public $c = 30;
        public $id;
        public static $inst = 0;
        public function __construct() {
                $this->id = ++self::$inst;
                echo "Instance #" . $this->id . " created.";
        }
        public function __clone() {
                // $this si riferisce all'istanza clonata
                echo "Instance #" . $this->id . " cloned.";
                $this->a = "new value";
                echo $this->a;
        }       
}
// stampa "Instance #1 created."
$obj1 = new MyClass();
// stampa "Instance #1 cloned"
// stampa "new value"
$obj2 = clone $obj1;
// stampa 10
echo $obj1->a;
// stampa "new value"
echo $obj2->a;

Conclusione

In questa e nella precedente lezione abbiamo potuto osservare dettagliatamente tutti i metodi magici dichiarabili all'interno delle classi con PHP5 e soprattutto la loro assoluta importanza. Un metodo magico può riscuotere un ruolo importantissimo nelle gerarchie di oggetti di qualsiasi tipologia di applicazione, poiché permette di controllare con precisione una determinata situazione altrimenti inaccessibile.

Conoscere e padroneggiare questi metodi (o almeno i più importanti) è di fondamentale importanza per lo sviluppo di applicazioni OOP avanzate.

Con questa lezione termina la parte teorica della guida. A questo punto tutti i concetti fondamentali della programmazione orientata agli oggetti offerta da PHP sono stati dettagliatamente affrontati. È arrivato dunque il momento di affrontare la parte pratica conclusiva, che ci permetterà di realizzare un'applicazione OOP reale mettendo in pratica la maggior parte dei concetti che abbiamo imparato nel corso di queste lezioni.

Ti consigliamo anche