Con la versione 5 di PHP è stato completamente rivoluzionato il supporto alla programmazione ad oggetti. Nella versione 4 era possibile programmare ad oggetti, ma le enormi possibilità della classica programmazione ad oggetti erano fortemente limitate dalla mancanza di un supporto adeguato da parte del linguaggio. Questo perchè il supporto alla programmazione ad oggetti è entrato a far parte di PHP come qualcosa di aggiuntivo, non nato assieme al linguaggio, che era stato inizialmente pensato per essere solamente procedurale.
Da PHP 5 le cose sono fortemente cambiate, e il supporto alla programmazione ad oggetti non ha ora nulla da invidiare a quello di altri più blasonati linguaggi, come Java. In questo articolo vedremo come costruire una classe in PHP. Diamo assolutamente per scontato che si sappia cosa sia la programmazione ad oggetti. Lo scopo dell’articolo non è spiegare questo paradigma di programmazione, bensì come applicarlo in PHP; anche perchè per spiegare il paradigma ad oggetti servirebbe ben più di un articolo.
Definizione di una classe
Una classe in PHP, come in tati altri linguaggi (tra cui ad esempio C++ e Java), si definisce con la keyword class, seguita dal nome della classe. Una classe può avere una serie di attributi, o proprietà, e una serie di metodi, o funzioni membro.
<?php
// Definizione della classe MyClass
class MyClass {
var $att1; // primo attributo
var $att2; // secondo attributo
// Definizione di un metodo
function myMethod(){
echo "Sono un metodo";
}
}
?>
In questo primo esempio abbiamo costruito la classe MyClass, con i due attributi $att1 e $att2, e un metodo myMethod(). Un attributo è una normale variabile, ma dichiarata tramite la keyword var, e un metodo è una normale funzione, dichirata quindi con la classica keyword function. Ovviamente è possibile definire un costruttore. A differenza di Java e C++, e anche di PHP4, il costruttore non deve avere lo stesso nome della classe, ma deve invece chiamarsi __construct(). Per instanziare gli attributi dell’oggetto, e in generale per riferirsi ad essi, si usa la sintassi $this->attributo. La stessa sintassi si utilizza anche per chiamare un metodo della classe su un oggetto. Quindi per chiamare myMethod() su un oggetto $obj della classe MyClass si usa $obj->myMethod(). Per chi conosce C++ questa è una sintassi familiare. $this può essere visto come un puntatore all’oggetto corrente. Con l’operatore -> ci si riferisce ad un attributo, o ad un metodo, dell’oggetto "puntato" dal puntatore. Ecco un esempio che imposta gli attributi a null.
<?php
// Definizione della classe MyClass
class MyClass {
var $att1; // primo attributo
var $att2; // secondo attributo
// Costruttore
function __construct(){
$this->att1 = null;
$this->att2 = null;
}
// Definizione di un metodo
function myMethod(){
echo "Sono un metodo";
}
}
?>
Possiamo anche definire un distruttore. Sempre per chi conosce C++: il distruttore in PHP non ha la stessa funzione! In C++ il distruttore è necessario per eviare memory leaks. Il distruttore di PHP è invece molto simile al metodo finalize() di Java. E’ infatti una funzione che viene automaticamente chiamata dal garbage collector del motore di PHP quando nessuno sta più utilizzando l’oggetto, ovvero quando nessun altro script ha un riferimento all’oggetto. E’ molto utile ad esempio per effettuare la chiusura della connessione al database, o chiudere files. Similmente al costruttore, il distruttore deve chiamarsi __destruct(). Nel nostro caso il distruttore non fa nulla, e potremmo quindi anche non definirlo.
<?php
// Definizione della classe MyClass
class MyClass {
var $att1; // primo attributo
var $att2; // secondo attributo
// Costruttore
function __construct(){
$this->att1 = null;
$this->att2 = null;
}
// Definizione di un metodo
function myMethod(){
echo "Sono un metodo";
}
// Distruttore
function __destruct(){
// ... codice del distruttore ...
}
}
?>
Due parole sull’overloading del costruttore
E’ il caso di chiarire subito una questione che potrebbe far sorgere dei dubbi a chi proviene da linguaggi fortemente tipizzati come Java o C++. L’overloading del costruttore in PHP 5 non è possibile. Tuttavia ciò non è un problema, dato che PHP permette, come C++ e al contrario di Java, di inserire valori di default per i parametri del costruttore. Se volessimo avere dei costruttori di questo tipo:
<?php
// Costruttore senza parametri
function __construct(){
// ... codice del costruttore ...
}
// Costruttore con un parametro
function __construct($a){
// ... codice del costruttore ...
}
// Costruttore con due parametri
function __construct($a, $b){
// ... codice del costruttore ...
}
?>
basterebbe in realtà definire un singolo costruttore, in questo modo:
<?php
// Un costruttore ne riassume tre
function __construct($a = null, $b = null, $c = null){
// ... codice del costruttore ...
}
?>
Grazie ai valori di default dei parametri abbiamo ottenuto l’effetto di 3 costruttori in uno solo, migliorando la sintesi e la leggibilità del codice.
E se voglio fare due costruttori che accettano lo stesso numero di parametri ma di tipo diverso? Beh, PHP non è fortemente tipizzato, e basterà quindi crearne uno solo, e all’interno del codice verificare il tipo del parametro dato. Ad esempio:
<?php
/* Riassume i seguenti tre costruttori:
* - costruttore senza parametri
* - costruttore con parametro int
* - costruttore con parametro string
*/
function __construct($a = null){
if (is_null($a)){
// ... codice del costruttore senza parametri ...
}
else if (is_int($a)){
// ... codice del costruttore con parametro int ...
}
else if (is_string($a)){
// ... codice del costruttore con parametro string ...
}
}
?>
Come vedete, la possibilità di definire un solo costruttore non è un vero problema.