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

I metodi magici di PHP

Impariamo ad utilizzare i metodi magici di PHP, utilizzati per reagire a diversi eventi e scenari all'interno degli oggetti. Conoscere questi metodi è di fondamentale importanza per lo sviluppo di applicazioni OOP avanzate. Un metodo magico può avere un ruolo fondamentale nelle gerarchie di oggetti di qualsiasi tipologia di applicazione, poiché permette di controllare con precisione situazione e proprietà altrimenti inaccessibili.
Impariamo ad utilizzare i metodi magici di PHP, utilizzati per reagire a diversi eventi e scenari all'interno degli oggetti. Conoscere questi metodi è di fondamentale importanza per lo sviluppo di applicazioni OOP avanzate. Un metodo magico può avere un ruolo fondamentale nelle gerarchie di oggetti di qualsiasi tipologia di applicazione, poiché permette di controllare con precisione situazione e proprietà altrimenti inaccessibili.
Link copiato negli appunti

Come anticipato nelle lezioni precedenti, PHP fornisce alcuni metodi magici, i quali ricoprono un ruolo molto importante nella programmazione OOP di PHP. A questo punto della guida, abbiamo già analizzato dei metodi magici: __construct, __destruct() e __clone(). In questa lezione analizzeremo anche questi metodi, attivati al verificarsi di determinati eventi e contrassegnati dal doppio underscore __ iniziale("__") .

Attenzione: PHP tratta tutte le funzioni che iniziano con "__" come metodi magici. Si consiglia quindi di non implementare nomi di funzioni con doppio underscore __ iniziale.

Introduzione ai metodi magici in PHP

Di seguito un elenco dei principali metodi magici disponibili con PHP, essi verranno analizzanti dettagliatamente nei prossimi paragrafi:

Medodo Descrizione
__construct() Il costruttore della classe. Chiamato quando si vuole creare un'istanza della classe.
__destruct() Il distruttore della classe. Questo metodo magico viene chiamato per distruggere o deallocare gli oggetti.
__call() Chiamato quando si cerca di effettuare un'invocazione ad un metodo che non esiste o un metodo privato.
__callStatic() Viene richiamato un metodo inaccessibile (nel contesto statico).
__get() Chiamato quando si tenta di leggere una proprietà inaccessibile.
__set() Chiamato quando si tenta di scrivere una proprietà non accessibile.
__isset() Chiamato quando si invocano le funzioni isset() su campi non accessibili.
__unset() Chiamato quando si invoca la funzione unset() su un campo non accessibile.
__sleep() Viene richiamata la funzione serialize() con un'istanza.
__wakeup() Viene richiamata la funzione unserialize() con un'istanza.
__toString() Chiamato quando l'oggetto è trattato come una stringa, ad esempio, quando si utilizza il comando echo.
__invoke() Chiamato quando si tenta di utilizzare un oggetto come funzione.
__set_state() Metodo statico chiamato quando si invoca la funzione var_export() sulla classe.
__clone() Chiamato quando si invoca il comando clone su un oggetto per generarne una copia.

__construct e __destruct

__construct(), è il metodo magico che PHP invocata per creare istanze di oggetti di classe. Accetta qualsiasi numero di argomenti. Il metodo __destruct, viene chiamato automaticamente dal motore PHP prima che l'oggetto sia distrutto. Risulta molto utile, ad esempio, per chiudere gli handle dei files, le connessioni al database o altre operazioni da eseguire prima che l'oggetto venga distrutto.

<?php
class test{
	// dichiarazione costruttore
	function __construct() {
		echo "Costruttore ";
	}
	// dichiarazione distruttore
	function __destruct() {
		echo "Distruttore ";
	}
}
$obj = new test(); //__construct viene automaticamente chiamato
// distruzione delle istanze
unset($objT); // stampa "Distruttore"
?>

__call e __callStatic

Il metodo __call viene chiamato ogni volta che si cerca di eseguire un metodo che non esiste. Accetta 2 parametri: il nome della funzione (metodo chiamato) e l'array contenente i parametri passati al metodo. Per i metodi in un contesto statico si consiglia di utilizzare __callStatic().

<?php
class MyClass {
	public function __call($name, $arguments) {
		echo "<br>"."Chiamata metodo '$name' " . implode(', ', $arguments). "\n";
	}
	public static function __callStatic($name, $arguments) {
		echo "<br>"."Chiamata metodo Static '$name' " . implode(', ', $arguments). "\n";
	}
}
$obj = new MyClass;
$obj->runTest('Oggetto nel contesto');
MyClass::runTest('Oggetto nel contesto statico');
?>

__set e __get

Il metodo __set, viene chiamato quando si cerca di modificare una proprietà inesistente , mentre, il metodo __get, viene chiamato quando si tenta di leggere una proprietà inesistente. Il seguente esempio illustra l'applicazione dei 2 metodi.

<?php
class Test {
	private $testArray = array();
	public function __set($prop, $valore) {
		$this->testArray[$prop] = $valore;
	}
	public function __get($prop) {
		return $this->testArray[$prop];
	}
}
$obj = new Test();
if (!isset($obj->nome)) {
	$obj->nome = "Giulia";
	}
echo $obj->nome; // Giulia
?>

__isset e __unset

Oltre ai metodi __set e __get ci sono altri due metodi utili per esaminare l'impostazione di una proprietà inesistente: __isset e __unset.

__isset() controlla se la proprietà è stata impostata o meno. Accetta un argomento, ossia la proprietà che si desidera testare. Si chiama il metodo __isset anche per la verifica di proprietà vuote, utilizzando la funzione empty(). __unset() svolge la funzione opposta a quella del metodo __isset(), riceve quindi un argomento che è il nome della proprietà che si vuole disinserire o eliminare.

<?php
class Test {
	private $testArray = array();
	public function __set($prop, $valore) {
		$this->testArray[$prop] = $valore;
	}
	public function __get($prop) {
		return $this->testArray[$prop];
	}
	public function __isset($prop) {
		return isset($this->testArray[$prop]);
	}
	public function __unset($prop) {
		unset($this->testArray[$prop]);
	}
}
$obj = new Test();
if (!isset($obj->name)) {
	$obj->name = "Giulia";
}
echo $obj->name; // Giulia
?>

__sleep e __wakeup

I metodi magici __sleep() e __wakeup() sono chiamati durante la serializzazione di oggetti. Questi forniscono un metodo per ripulire e ripristinare un oggetto prima della serializzazione; quindi in caso di serializzazione e deserializzazione di oggetti, PHP controllerà automaticamente, la presenza nella classe dei due metodi.

__sleep() viene chiamato quando l'oggetto di una classe sta per essere serializzato. Questo metodo non accetta alcun parametro e restituisce un array contenente i nomi delle proprietà da serializzare e si usa generalmente per operazioni di cleanup.

__wakeup () svolge la funzione opposta a quella del metodo __sleep(). Viene Chiamato quando l'oggetto di una classe sta per essere deserializzato, ad esempio, per riaprire le connessioni ai database o alle risorse esterne. Questo metodo non accetta alcun parametro né restituisce nulla. Si analizzi un esempio a riguardo:

<?php
class Person {
	private $name;
	private $cf;
	public function setName($name) {
			$this->name = $name;
	}
	public function getName() {
			return $this->name;
	}
	public function setCF($cc) {
			$this->cf = $cc;
	}
	public function getCF() {
			return $this->cf;
	}
	public function __sleep() {
			return array("name");
	}
	public function __wakeup() {
			if($this->name == "Giulia") {
			$this->cf = "CZZGLI12A44E123K";
			}
	}
}
$c = new Person();
$c->setName("Giulia");
$c->setCF("CZZPGS80C80703T");
$data = serialize($c)."\n";
var_dump(unserialize($data));
?>

__toString

Questa funziona viene utilizzata per restituire la rappresentazione come stringa di un oggetto.

<?php
class Person {
	public function __construct($name) {
		$this->name = $name;
	}
	public function __toString() {
		return $this->name;
	}
}
$person1 = new Person('Giulia');
echo $person1;
?>

Senza l'utilizzo del metodo __toString() il tentativo di visualizzare un oggetto come stringa restituirebbe un errore fatale.

Catchable fatal error: Object of class Person could not be converted to string in...

__set_state e __invoke

__set_state viene azionato quando si esporta un oggetto tramite la funzione var_export() ed accetta un array che avrà le coppie key/value impostate ai nomi/valori delle proprietà esportate. Il secondo, __invoke, viene richiamato quando si usa un oggetto come una funzione.

<?php
// __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 MyClass2 {
	public function __invoke($x) {
		echo $x;
	}
}
$obj1 = new MyClass2();
$obj1(5);
?>

__clone

Come visto nella lezione dedicata alla clonazione degli oggetti, il metodo __clone fornisce tutte le funzionalità per la clonazione completa e indipendente di un oggetto: crea un nuovo oggetto identico all'originale copiando tutte le variabili membro.

<?php
class Person {
	public $nome;
	public $cognome;
	public $azienda;
	// aggiunta all'interno della definizione della classe del metodo __clone().
	public function __clone(){
		//associazione
		$this->azienda = "Warner Bros.";
	}
}
class Azienda {
	public $nomeAzienda;
}
$aziendaA = new Azienda();
$aziendaA->nomeAzienda="Html.it";
$person1 = new Person();
$person1->nome="Giulia";
$person1->cognome="Q";
$person1->azienda= $aziendaA;
$person3 = clone $person1;
$person3->nome="Giuseppe";
var_dump($person1);
var_dump($person3);
?>

Non appena PHP eseguirà la clonazione del nuovo oggetto, verrà invocato il metodo __clone() e l'oggetto clonato sarà accessibile.

Ti consigliamo anche