Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Back-End
Code

PHP orientato agli oggetti per principianti

by
Difficulty:IntermediateLength:LongLanguages:

Italian (Italiano) translation by Sabrina Pampaloni (you can also view the original English article)

Per molti programmatori PHP la programmazione orientata agli oggetti è un concetto che spaventa, pieno di sintassi complicata e di altri ostacoli. Come ho scritto nei dettagli nel mio libro, Pro PHP and jQuery  (in inglese), imparerete i concetti dietro la programmazione orientata agli oggetti (in inglese object-oriented programming, OOP), uno stile di scrittura di codice dove si raggruppano azioni collegate in classi per poter creare codice più compatto e più efficiente.

Capire la programmazione orientata agli oggetti

La programmazione orientata agli oggetti è uno stile di scrittura di codice che permette agli sviluppatori di raggruppare compiti simili in classi. Questo aiuta a far sì che il codice segua il principio "non ripeterti" (in inglese don't repeat yourself, DRY) e sia facile da manutenere.

"La programmazione orientata agli oggetti è uno stile di scrittura di codice che permette agli sviluppatori di raggruppare compiti simili in classi".

Uno dei maggiori vantaggi del principio di programmazione DRY è che, se cambia un pezzo di informazione nel vostro programma, di solito è necessaria una sola modifica per aggiornare il codice. Uno dei più grandi incubi per gli sviluppatori è manutenere codice dove i dati sono dichiarati mille volte, il che vuol dire che ogni modifica al programma diventa un gioco infinitamente più frustrante di Dov'è Wally? per cercare le funzionalità e i dati duplicati.

L'OOP può intimidire molti sviluppatori, perché introduce sintassi nuova e, a un primo sguardo, appare ben più complessa del semplice codice procedurale, o riga per riga. Comunque, se la si guarda più da vicino, l'OOP è in realtà un approccio molto immediato e sostanzialmente più semplice alla programmazione.

Capire gli oggetti e le classi

Prima di andare troppo a fondo nelle sottigliezze dell'OOP è necessaria una comprensione di base delle differenze tra oggetti e classi. Questa sezione esaminerà i componenti fondamentali delle classi, le loro differenti capacità e alcuni dei loro usi.

Riconoscere le differenze tra oggetti e classi

Foto di Instant Jefferson e di John Wardell

Gli sviluppatori iniziano a parlare di oggetti e di classi, e questi sembrano essere termini interscambiabili. Non è così, comunque.

Tanto per cominciare, c'è confusione nell'OOP: gli sviluppatori esperti iniziano a parlare di oggetti e di classi, e questi sembrano essere termini interscambiabili. Non è così, comunque, anche se la differenza può essere difficile da iniziare a capire subito.

Una classe, per esempio, è come un progetto per una casa. Definisce su carta la forma della casa, con relazioni ben definite e pianificate tra le diverse parti della casa, anche se la casa non esiste.

Un oggetto, quindi, è come la casa vera e propria costruita secondo quel progetto. I dati memorizzati nell'oggetto sono come il legno, i cavi e il cemento che compongono la casa: senza essere messi insieme secondo il progetto, sono solo un mucchio di roba. Comunque, quando si mette tutto insieme, diventa una casa utile e organizzata.

Le classi formano la struttura dei dati e delle azioni e usano queste informazioni per costruire gli oggetti. Si può costruire più di un oggetto contemporaneamente dalla stessa classe, e ciascuno è indipendente dagli altri. Continuando con la nostra analogia edilizia, è simile al modo di costruire un intero isolato dallo stesso progetto: 150 case diverse che hanno tutte lo stesso aspetto ma hanno dentro famiglie diverse
e un diverso arredamento.

Strutturare le classi

La sintassi per creare una classe è piuttosto immediata: si dichiara una classe usando la parola chiave class, seguita dal nome della classe e da un insieme di parentesi graffe ({}):

Dopo aver creato la classe, si può istanziare la classe e memorizzarla in una variabile usando la parola chiave new:

Per vedere il contenuto della classe si usa var_dump():

Provate questo procedimento mettendo il codice precedente in un nuovo file di nome test.php nella cartella [locale] di test:

Caricate la pagina nel vostro browser all'URL http://localhost/test.php e si dovrebbe vedere quanto segue:

Nella sua forma più semplice, avete appena completato il vostro primo script OOP.

Definire le proprietà di una classe

Per aggiungere dati a una classe si usano le proprietà, o variabili specifiche della classe. Queste funzionano esattamente come le variabili normali, tranne per il fatto che sono legate all'oggetto e perciò vi si può accedere solo usando l'oggetto.

Per aggiungere una proprietà a MyClass aggiungete il seguente codice al vostro script:

La parola chiave public determina la visibilità della proprietà, sulla quale imparerete un po' più avanti in questo capitolo. In seguito si dà un nome alla proprietà usando la sintassi standard per le variabili e si assegna un valore (sebbene le proprietà delle classi non abbiano bisogno di un valore iniziale).

Per leggere questa proprietà e visualizzarla nel browser si fa riferimento all'oggetto da cui leggere e alla proprietà da leggere:

Poiché possono esistere multiple istanze di una classe, se non si facesse riferimento al singolo oggetto lo script non sarebbe in grado di determinare da quale oggetto leggere. L'uso della freccia (->) è un costrutto OOP per accedere alle proprietà e ai metodi contenuti in un dato oggetto:

Modificate lo script in test.php per leggere la proprietà invece di visualizzare l'intera classe modificando il codice così:

Se ricaricate il browser ora vedrete quanto segue:

Definire i metodi di una classe

I metodi sono funzioni specifiche della classe. Si definiscono all'interno della classe come metodi le singole azioni che un oggetto sarà in grado di eseguire.

Per esempio, per creare metodi che scrivono e leggono il valore della proprietà $prop1 della classe aggiungete al vostro codice quanto segue:

Nota — l'OOP permette agli oggetti di far riferimento a loro stessi usando $this. Quando si lavora all'interno di un metodo si usa $this come si usarebbe il nome dell'oggetto al di fuori della classe.

Per usare questi metodi li si chiamano come funzioni normali, ma prima si fa riferimento all'oggetto al quale appartengono. Leggete la proprietà da MyClass, modificate il suo valore e leggetela di nuovo facendo la modifica seguente:

Ricaricate il browser e vedrete quanto segue:

"Il potere dell'OOP si nota quando si usano istanze multiple della
stessa classe".

Quando ricaricate il risultato nel browser appare quello che segue:

Come potete vedere, l'OOP considera gli oggetti entità separate, e ciò permette una facile separazione dei vari pezzi di codice in piccoli gruppi separati.

Metodi magici nell'OOP

Per rendere più facile l'uso degli oggetti il PHP fornisce anche un certo numero di metodi magici, o metodi speciali che vengono chiamati quando occorrono determinate azioni comuni all'interno degli oggetti. Questo permette agli sviluppatori di eseguire diversi compiti utili con una certa facilità.

Usare i costruttori e i distruttori

Quando viene istanziato un oggetto spesso si desidera impostare alcune cose subito dall'inizio. Per gestire questo il PHP fornisce il metodo magico __construct(), che viene chiamato automaticamente ogni volta che si crea un nuovo
oggetto.

Al fine di illustrare il concetto dei costruttori, aggiungiamo a MyClass un costruttore che restituirà un messaggio ogni volta che si crea una nuova istanza della classe:

Nota __CLASS__ restituisce il nome della classe nella quale è chiamato, per questo è noto come costante magica. Ci sono varie costanti magiche disponibili, potete leggere di più a questo proposito nel manuale PHP.

Ricaricare il file nel browser produrrà il seguente risultato:

Per chiamare una funzione quando l'oggetto viene distrutto è disponibile il metodo magico __destruct(). Questo è utile per fare pulizia nelle classi (per esempio per chiudere una connessione a un database).

Visualizzate un messaggio quando viene distrutto l'oggetto definendo il metodo magico
__destruct() in MyClass:

Con un distruttore definito, ricaricare il file di test darà il seguente risultato:

"Quando si raggiunge la fine di un file il PHP libera automaticamente tutte le risorse".

Per attivare esplicitamente il distruttore si può distruggere l'oggetto usando la
funzione unset():

Ora il risultato cambia come segue se caricato nel browser:

Convertire in stringa

Per evitare un errore se uno script cerca di visualizzare MyClass come stringa si usa un altro metodo magico di nome __toString().

Senza __toString() un tentativo di visualizzare l'oggetto come stringa darebbe un errore fatale. Tentativo di usare echo per visualizzare l'oggetto senza che ci sia un metodo magico:

Questo dà il seguente risultato:

Per evitare questo errore aggiungiamo un metodo __toString():

In questo caso un tentativo di convertire l'oggetto in stringa dà come risultato una chiamata al metodo getProperty(). Caricate lo script nel browser per vedere il risultato:

 Consiglio — In aggiunta ai metodi magici discussi in questa sezione, ne sono disponibili altri. Per una lista completa dei metodi magici si veda la pagina del manuale PHP.

Usare l'ereditarietà

Le classi possono ereditare i metodi e le proprietà di un'altra classe usando la parola chiave extends. Per esempio, per creare una seconda classe che estende MyClass e aggiunge un metodo si può aggiungere il seguente codice al file:

Ricaricando il file nel browser si ha il seguente risultato:

Sovrascrivere proprietà e metodi ereditati

Per modificare il comportamento di una proprietà o di un metodo esistente nella nuova classe si può semplicemente sovrascriverlo dichiarandolo di nuovo nella nuova classe:

Questo cambia il risultato nel browser:

Conservare la funzionalità originale del metodo quando si sovrascrivono i metodi

Per aggiungere una nuova funzionalità a un metodo ereditato conservando intatto il metodo originale si usa la parola chiave parent con l'operatore di risoluzione di visibilità (::):

Questo restituisce il risultato sia del costruttore padre che del costruttore della nuova classe:

Assegnare la visibilità alle proprietà e ai metodi

Per un maggior controllo sugli oggetti si assegna una visibilità ai metodi e alle proprietà. Questo controlla come e da dove si può accedere a metodi e proprietà. Ci sono tre parole chiave di visibilità: public, protected e private. Oltre alla visibilità, una proprietà o un metodo può essere dichiarato static, che permette l'accesso senza un'istanziazione della classe.

"Per un maggior controllo sugli oggetti si assegna una visibilità ai metodi e alle proprietà".

Nota — La visibilità è una nuova funzionalità dal PHP 5 in poi. Per informazioni sulla compatibilità OOP con il PHP 4 si veda la pagina del manuale PHP.

Proprietà e metodi pubblici

Tutte le proprietà e tutti i metodi usati finora sono stati pubblici. Questo significa che vi si può accedere ovunque, sia dentro la classe che fuori.

Proprietà e metodi protetti

Quando una proprietà o un metodo è dichiarato protected vi si può accedere solo all'interno della classe stessa o delle sue classi discendenti (classi che estendono la classe che contiene il metodo protetto).

Dichiarate il metodo getProperty() protetto in MyClass e provate ad accedere ad esso direttamente al di fuori della classe:

Provando a eseguire questo script appare il seguente errore:

Ora create un metodo in MyOtherClass che chiami il metodo getProperty():

Questo genera il risultato desiderato:

Proprietà e metodi privati

Una proprietà o un metodo dichiarato private è accessibile solo all'interno della classe che lo definisce. Questo vuol dire che anche se una nuova classe estende la classe che definisce una proprietà privata, quella proprietà o quel metodo non sarà affatto disponibile all'interno della classe figlia.

Per dimostrare questo, dichiarate privato getProperty() in MyClass e provate a chiamare callProtected() da
MyOtherClass:

Ricaricate il browser e apparirà il seguente errore:

Proprietà e metodi statici

A una proprietà o a un metodo dichiarato static si può accedere senza prima istanziare la classe; si scrive semplicemente il nome della classe, l'operatore di risoluzione di visibilità e il nome della proprietà o del metodo.

"Uno dei vantaggi maggiori di usare proprietà statiche è che mantengono in memoria il loro valore per tutta la durata dello script".

Per dimostrare questo aggiungete una proprietà statica di nome $count e un metodo statico di nome plusOne() a MyClass. Poi impostate un ciclo do...while per visualizzare il valore incrementato di $count finché il valore è minore di 10:

Nota — Quando si accede a proprietà statiche, il segno del dollaro
($) viene dopo l'operatore di risoluzione di visibilità.

Quando si carica lo script nel browser il risultato è il seguente:

Commentare con i DocBlock

"Lo stile di commento DocBlock è un metodo
ampiamente accettato per documentare le classi".

Sebbene non faccia ufficialmente parte dell'OOP, lo stile di commento DocBlock è un metodo ampiamente accettato per documentare le classi. Oltre a fornire uno standard che gli
sviluppatori usano quando scrivono codice, è anche stato adottato da molti dei più popolari strumenti di sviluppo software, come Eclipse e NetBeans, e sarà usato per usare suggerimenti di codice.

Si definisce un DocBlock usando un commento a blocco che inizia con un asterisco in più:

Il vero potere del DocBlock sta nella capacità di usare i tag, che iniziano con una chiocciola (@) immediatamente seguita dal nome del tag e dal suo valore. I tag dei DocBlock permettono agli sviluppatori di definire gli autori di un file, la licenza per una classe, informazioni su proprietà e metodi e altre informazioni utili.

Seguono i tag più comunemente usati:

  • @author: Con questo tag si elenca l'autore dell'elemento corrente (che può essere una classe, un file, un metodo o un qualunque pezzo di codice). Si possono usare nello stesso DocBlock più tag author se si vuole dar credito a più di un autore. Il formato per il nome di un autore è Mario Rossi <mario.rossi@email.com>.
  • @copyright: Questo significa l'anno di copyright e il nome del detentore del copyright per l'elemento corrente. Il formato è 2010 Detentore Del Copyright.
  • @licenza: Questo è un link alla licenza per l'elemento corrente. Il formato per le informazioni sulla licenza è
    http://www.esempio.com/percorso/alla/licenza.txt Nome Della Licenza.
  • @var: Contiente il tipo e la descrizione di una variabile o proprietà della classe. Il formato è tipo descrizione dell'elemento.
  • @param: Questo tag mostra il tipo e la descrizione del parametro di una funzione o metodo. Il formato è tipo $nome_elemento descrizione dell'elemento
  • @return: Questo tag fornisce il tipo e la descrizione del valore restituito da una funzione o metodo. Il formato è tipo descrizione dell'elemento restituito.

Un esempio di classe commentata con i DocBlock ha questo aspetto:

Se guardate bene la classe precedente, i vantaggi dei DocBlock sono chiari: tutto è ben definito in modo che il prossimo sviluppatore possa prendere il codice e non si debba mai chiedere cosa fa o cosa dovrebbe contenere un pezzo di codice.

Confronto tra codice orientato agli oggetti e procedurale

Non esiste un modo giusto o un modo sbagliato di scrivere codice. Detto questo, questa sezione delinea una forte argomentazione per adottare un approccio orientato agli oggetti nello sviluppo di software, specialmente in grandi progetti.

Ragione 1: Facilità di implementazione

"Anche se può intimorire all'inizio, l'OOP in realtà fornisce un approccio più facile per gestire i dati".

Anche se può intimorire all'inizio, l'OOP in realtà fornisce un approccio più facile per gestire i dati. Poiché un oggetto può memorizzare dati al suo interno, non è necessario passare variabili da una funzione all'altra perché tutto funzioni correttamente.

Inoltre, poiché possono esistere contemporaneamente più istanze della stessa classe, è infinitamente più facile gestire grandi insiemi di dati. Per esempio, supponiamo di dover elaborare le informazioni di due persone in un file. Ci servono i nomi, le occupazioni e le età.

L'approccio procedurale

Questo è l'approccio procedurale al nostro esempio:

Quando si esegue, il codice restituisce quanto segue:

Sebbene il codice non sia necessariamente pessimo, c'è molto da tener presente quando si scrive. L'array con gli attributi della persona in questione deve essere passato e restituito da ogni chiamata di funzione, cosa che lascia un margine di errore.

Per rendere l'esempio più pulito, sarebbe desiderabile lasciare allo sviluppatore meno cose possibili. Alle funzioni dovrebbe essere necessario passare solo le informazioni assolutamente essenziali per l'operazione corrente.

È qui che arriva l'OOP ad aiutare a rendere le cose più pulite.

L'approccio OOP

Ecco l'approccio OOP al nostro esempio:

Questo restituisce il seguente risultato nel browser:

C'è un po' più di lavoro iniziale per realizzare l'approccio orientato agli oggetti, ma una volta che la classe è definita, creare e modificare una persona è un attimo; le informazioni di una persona non devono essere passate o restituite dai metodi, e ad ogni metodo si passano solo le informazioni assolutamente essenziali.

"L'OOP ridurrà significativamente il vostro carico di lavoro se implementata correttamente".

Su una piccola scala questa differenza potrà non sembrare granché, ma come la vostra applicazione crescerà di dimensione l'OOP ridurrà significativamente il vostro carico di lavoro se implementata correttamente.

Consiglio Non tutto deve essere orientato agli oggetti. Una funzione rapida che gestisce qualcosa di piccolo in un posto solo all'interno dell'applicazione non deve necessariamente far parte di una qualche classe. Usate il vostro giudizio quando dovete decidere tra un approccio procedurale e uno orientato agli oggetti.

Ragione 2: Migliore organizzazione

Un altro vantaggio dell'OOP è come si presta bene ad essere facilmente impacchettata e catalogata. Ogni classe si può generalmente tenere in un suo file separato, e se si una una convenzione uniforme per i nomi accedere alle classi è estremamente semplice.

Supponiamo di avere un'applicazione con 150 classi che sono chiamate dinamicamente da un file di controllo alla radice del filesystem della nostra applicazione. Tutte le 150 classi seguono la convenzione per i nomi class.nomeclasse.inc.php e risiedono nella cartella inc della nostra applicazione.

Il file di controllo può implementare la funzione __autoload() del PHP per caricare dinamicamente solo le classi necessarie quando vengono chiamate, piuttosto che includerle tutte e 150 nel file di controllo nel caso che servano o trovare qualche modo abile per includere i file nel nostro codice:

Avere ogni classe in un file separato rende anche il codice più portabile e più facile da riutilizzare in nuove applicazioni senza troppo copia e incolla.

Ragione 3: Manutenzione più facile

A causa della natura più compatta dell'OOP quando è fatta correttamente, le modifiche nel codice sono di solito molto più facili da individuare e da fare che in una lunga implementazione procedurale a spaghetti.

Se un array particolare deve avere un nuovo attributo, un pezzo di software procedurale può richiedere (nel caso peggiore) che il nuovo attributo sia aggiunto a ogni funzione che usa l'array.

Un'applicazione OOP potrebbe potenzialmente essere aggiornata facilmente aggiungendo la nuova proprietà e poi aggiungendo i metodi che gestiscono quella proprietà.

Molti dei vantaggi coperti in questa sezione sono il prodotto della OOP in combinazione con le pratice di programmazione DRY: È decisamente possibile creare codice procedurale facile da manutenere che non causi incubi, ed è altrettanto possibile creare pessimo codice orientato agli oggetti. [Pro PHP and jQuery] cercherà di dimostrare che una combinazione di buone abitudini quando si scrive codice insieme all'OOP genera codice che è facile da leggere e da manutenere.

Riassunto

A questo punto dovreste sentirvi a vostro agio con lo stile di programmazione orientato agli oggetti. Imparare l'OOP è un buon modo per portare la vostra programmazione al livello successivo. Se implementata correttamente, la OOP vi aiuterà a produrre codice facile da leggere, facile da manutenere, portabile e che risparmierà (a voi e agli sviluppatori che lavorano con voi) ore di lavoro in più. Siete bloccati su qualcosa che non è stato trattato in questo articolo? State già usando l'OOP e avete consigli per i principianti? Commentate!

Nota dell'autore — Questo tutorial era un estratto da Pro PHP and jQuery (Apress, 2010).

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.