La programmazione ad oggetti in PHP ha preso piede parecchi anni fa con l'avvento di PHP 4, e si è consolidata con PHP 5. Prima di introdurre le nozioni pratiche necessarie per muovere i primi passi verso lo stile di programmazione OOP (Object Oriented Programming), è bene precisare alcuni limiti del paradigma. I vantaggi di PHP, rispetto ad altre tecnologie utilizzate negli ambienti enterprise (come ad esempio Java), è da sempre la velocità e semplicità dello sviluppo, che riduce i costi di un progetto web rispetto a scelte più “robuste”. Di contro PHP presenta alcuni limiti nel rigore, che vanno interpretati come il rovescio della medaglia: è proprio l'assenza di rigore architetturale e sintattico che permette a PHP di essere più semplice, riducendo i tempi di sviluppo del codice.

Questa filosofia si riflette anche nello stile di programmazione OOP offerta da PHP: hanno ragione i puristi quando affermano che PHP non è un linguaggio Object Oriented. La programmazione OOP non significa solamente usare classi e oggetti, ma implica molte altre caratteristiche tecniche che mancano nel PHP. Ciò spiega perché alcuni programmatori PHP di lunga esperienza non percepiscono i vantaggi della programmazione ad oggetti. Di fatto hanno ragione: tutto (o quasi) ciò che si può realizzare in PHP usando un approccio ad oggetti, può essere realizzato scrivendo del codice “alla vecchia maniera”.

Per questo motivo, quando parliamo del PHP, sarebbe più corretto dire “programmazione in stile OOP” piuttosto che “programmazione OOP”. In parole semplici: PHP permette di usare molte strutture e sintassi della programmazione OOP senza essere veramente una tecnologia costruiti sugli oggetti. Se pensiamo alla programmazione OOP come ad un'autovettura alimentata a GPL, si potrebbe dire che il PHP è un'auto nata a benzina sulla quale abbiamo montato un impianto GPL (quello col bombolone nel portabagagli, per intenderci). Fintanto che ci limitiamo a guidare e a far rifornimento, possiamo tranquillamente affermare di andare a GPL: solamente aprendo il cofano (o il portabagagli) ci potremmo accorgere di qualcosa di strano.

Detto questo possiamo introdurre le nozioni di base per applicare lo stile OOP al PHP. Iniziamo con l'esempio di una semplice classe

class testObject {

public $my_field = 3 ;

public function getFieldValue() { return $this->my_field ; }

public function setFieldValue($value) { $this->my_field = $value; }

}

il codice qui sopra va incluso tra le solite tag PHP (ovvero <?php e ?>) e salvato in un qualunque file con estensione PHP, che possiamo nominare come più ci piace (ad esempio test_class.php).

Commentiamo il codice qui sopra. Nel file test_class.php abbiamo definito la classe, ovvero codificato le istruzioni che serviranno per produrre le varie instanze (cioè oggetti) del tipo testObject: ogni oggetto avrà la propria identità, perché conterrà in genere valori diversi, pur condividendo le stessi API (Application Programming Interface) con tutte le altre instanze. Dopo la keyword class abbiamo specificato il nome della classe, ovvero testObject, che inizia con la prima graffa e si chiude con l'ultima: dentro queste due parentesi graffe troviamo le “istruzioni di comportamento” dell'oggetto. Queste istruzioni sono principalmente di due tipi: attributi (o campi) della classe, e metodi.

La classe testObject presenta un attributo di nome $my_field, che possiamo trattare come una normale variabile PHP. La classe inoltre ha due metodi: getFieldValue() e setFieldValue(). Il primo serve a restituire il valore dell'attributo $my_field, il secondo serve per assegnare un valore a tale attributo. La novità, all'interno dell'implementazione di questi metodi, è l'uso della keyword this.

Il concetto è semplice: così come nelle normali funzioni PHP si ha l'esigenza di distinguere tra variabili locali e variabili globali (le famose global), anche nella programmazione OOP serve un meccanismo per distinguere le variabili locali (cioè quelle del metodo) da quelle memorizzate come attributo di classe. La keyword this serve proprio a questo. Scrivendo

$this->my_field

precisiamo di stare facendo riferimento alla variabili $my_field definita come attributo di classe. E' importante notare il diverso utilizzo del simbolo $ (dollaro). Quando parliamo della variabile my_field in un contesto non ambiguo, come ad esempio nella sua definizione all'inizio della classe, usiamo il prefisso $ per dire che si tratta di una variabile, e scriviamo $my_field. Quando invece facciamo riferimento alla variabile my_field di un particolare oggetto, scriviamo

$this->my_field

per precisare che facciamo riferimento all'attributo my_field della variabile $this: omettiamo il simbolo $ davanti al nome della variabile my_field proprio per enfatizzare il fatto che adesso la variabile è $this! Per chiarire il concetto basta instanziare un oggetto di tipo testObject: creiamo una nuova pagina PHP e scriviamo

include_once('test_class.php') ;

$obj_1 = new testObject() ;

$obj_2 = new testObject() ;

$obj_1->setFieldValue(12) ;

$obj_2->setFieldValue(42) ;

echo 'Value 1: '.$obj_1->getFieldValue().'<br/>';

echo 'Value 2: '.$obj_2->getFieldValue().'<br/>';

L'esempio qui sopra mostra la caratteristica fondamentale della programmazione OOP: i due oggetti obj_1 e obj_2 sono instanze della stessa classe testObject, ma hanno vita diversa, perché possono trovarsi un un diverso stato (ovvero contenere diversi valori). In realtà l'esempio mostra anche un'altra caratteristica tipica della programmazione OOP: il principio di incapsulamento (encapsulation).

Incapsulare le variabili significa accedere ad essi attraverso metodi ben definiti, che non andremo mai più a cambiare, come in questo caso: usiamo setFieldValue per assegnare un valore all'attributo my_field e getFieldValue per leggerlo. Così facendo, se un domani dovesse cambiare il nome, tipo o logica relativa all'attributo my_field, le pagine che utilizzano gli oggetti di tipo testObject non si accorgeranno di niente: abbiamo incapsulato le informazioni all'interno della classe, dichiarando quali sono le API per accedere alla variabile senza dire nulla sulla natura della variabile.

Gli esperti di PHP potrebbero dire che non abbiamo introdotto nulla di nuovo: stato, incapsulamento e API sono concetti utilizzabili anche nella tradizionale programmazione strutturata, ed è vero (se il codice è scritto bene). Nelle prossime puntate vedremo come applicare questi concetti di base per ottenere nuovi risultati, difficili da realizzare nella programmazione tradizionale.