L'Introspection (introspezione) è, come suggerisce il nome, la capacità introspettiva degli oggetti, grazie alla quale possiamo analizzare e/o reperire informazioni utili su classi, interfacce, proprietà e metodi.
Alcune funzioni di Introspection
L'introspezione in PHP, permette di estrarre le informazioni di base sulle classi, come il loro nome, il nome della loro classe genitore e così via.
PHP offre un grande numero di funzioni che è possibile utilizzare per realizzare questo compito. Di seguito analizzeremo un esempio su come utilizzare alcune delle funzioni di introspezione del PHP.
Analizziamo innanzitutto alcune di queste funzioni:
Funzione | Descrizione |
---|---|
get_parent_class() | Per conoscere il parent o la classe di derivazione. |
class_exists() | Verifica se una classe è stata definita. |
get_class() | Restituisce il nome della classe di un oggetto. |
is_subclass_of() | Verifica se un oggetto ha una classe genitore. |
Per capire meglio il funzionamento dell'Introspection e le varie funzioni ad essa ricollegate è possibile proporre l'esempio seguente:
<?php
// dichiarazione della classe Introspezione
class Introspezione
{
// metodi
public function note() {
echo "Superclasse della classe Sample<br />";
}
}
// definizione della sottoclasse Sample
class Sample extends Introspezione
{
public function note() {
echo "Classe: ".get_class($this),"<br />";
echo "Classe di derivazione: ".get_parent_class($this), "<br />";
}
}
if (class_exists("Sample")) {
// istanzia un nuovo oggetto della classe Sample
$sample = new Sample();
$sample->note();
if (is_subclass_of($sample, "Introspezione")) {
echo "Sì, ".get_class($sample)." sottoclasse di Introspezione<br />";
}
else {
echo "No, ".get_class($sample)." non è sottoclasse di Introspezione<br />";
}
}
if (class_exists("Introspezione")) {
// istanzia un nuovo oggetto della classe Introspezione
$intro = new Introspezione();
echo "Classe: ".get_class($intro)."<br />";
$intro->note();
}
?>
L'output generato dal codice, proposto in precedenza, sarà il seguente:
Classe: Sample
Classe di derivazione: Introspezione
Si, Sample sottoclasse di Introspezione
Classe: Introspezione
Nell'esempio, controlliamo se la classe data è stata definita con il metodo class_exists()
. Questo metodo, accetta un argomento stringa che rappresenta il nome della classe da controllare e un valore booleano (opzionale) il quale indica se chiamare o meno __autoload
per default.
...
class_exists("Introspezione")
...
I metodi get_class()
e get_parent_class()
restituiscono, rispettivamente, il nome della classe di un oggetto o il nome della classe del suo genitore. Entrambi accettano come argomento un'istanza di un oggetto.
...
get_class($sample)
...
is_subclass_of($sample, "Introspezione")
...
Il metodo is_subclass_of()
accetta, come primo argomento, un'istanza di un oggetto e, come secondo argomento, una stringa che rappresenta il nome della classe genitore. Questa funzione restituisce TRUE se l'oggetto "$sample
" appartiene ad una classe che è una sottoclasse di "Introspezione".
...
is_subclass_of($sample, "Introspezione")
...
Si analizzi un secondo esempio basato questa volta sull'utilizzo delle seguenti funzioni:
Funzione | Descrizione |
---|---|
interface_exists() | Controlla se l'interfaccia è stata definita |
get_class_vars() | Restituisce le proprietà di default della classe |
get_declared_classes() | Restituisce un array con il nome delle classi definite |
get_class_methods() | Restituisce un array con i nomi dei metodi della classe. |
<?php
interface Person {
// costanti
const COSTANTE = "valore";
// definizione dei metodi
public function getName();
public function setName($name, $lastname);
}
class Student implements Person {
public $name = "";
public $lastname = "";
// implementazione dei metodi
public function getName(){
// corpo del Metodo
echo "$this->name $this->lastname";
}
public function setName($name, $lastname){
// corpo del Metodo
$this->name = $name;
$this->lastname = $lastname;
}
}
if (interface_exists("Person")) {
echo "L'interfaccia Person esiste <br><br />";
}
$classes = get_declared_classes();
echo "Sono disponibili le seguenti classi:<br />";
print_r($classes);
if (in_array("Student", $classes)) {
print "<br /><br />Classe Student dichiarata";
$student = new Student();
$methods = get_class_methods($student);
echo "<br /><br />Sono disponibili i seguenti metodi:<br />";
print_r($methods);
$vars = get_class_vars(get_class($student));
echo "<br /><br />Disponibili le seguenti propriet /à:";
print_r($vars);
echo "<br /><br />Il metodogetName() esiste per Student? ";
var_dump(method_exists($student, "getName"));
}
?>
L'output generato dal codice sarà il seguente:
L'interfaccia Person esiste
Sono disponibili le seguenti classi:
Array ( [0] => stdClass [1] => Exception [2] => ErrorException [3]...
Classe Student dichiarata
Sono disponibili i seguenti metodi:
Array ( [0] => getName [1] => setName )
Disponibili le seguenti proprietà:Array ( [name] => [lastname] => )
Il metodogetName() esiste per Student? bool(true)
Possiamo notare come il metodo interface_exists()
sia molto simile al metodo class_exists()
presente nel primo esempio. Infatti, questo metodo, controlla se l'interfaccia è stata definita e accetta un argomento stringa che rappresenta il nome dell'interfaccia e un valore booleano (opzionale) il quale indica se chiamare o meno __autoload
di default.
Il metodo get_declared_classes()
non accetta argomenti e restituisce un array con i nomi di tutte le classi definite (Il numero delle classi visualizzate varia in base a quali librerie sono state compilate/caricate in PHP).
Entrambi i metodi get_class_method()
e get_class_vars()
prendono in ingresso il nome della classe; mentre il primo restituisce un array con i nomi dei metodi della classe, il secondo restituisce un'array con le proprietà di default pubbliche della classe.
Conclusioni
Nel corso di questo articolo, abbiamo visto come utilizzare alcune delle funzioni (le più utili) di introspezione in PHP, rafforzando quindi le basi dell'OOP. Nel prossimo capitolo analizzeremo un'API che offre funzionalità simili all'introspezione: l'API Reflection.