Lo scopo principale della programmazione ad oggetti è rappresentato dalla necessità di riutilizzare e condividere codice, ma scrivere codice ben formattato non è sufficiente.
Nominare in maniera descrittiva le classi, i metodi e le variabili aiuta certamente ma non fornisce un contributo importante nella comprensione immediata dei parametri richiesti da un certo metodo o da un risultato. Ciò è ancora più vero in un linguaggio loosely typed come PHP dove le variabili non possono essere totalmente definite come appartenenti ad uno tipo (integer
, string
, array
, etc.), anche se nella versione 7 del linguaggio sono stati fatti passi da gigante in questa direzione.
Oltre alla necessità di rendere il codice più comprensibile ad altri componenti del team o ad utilizzatori futuri delle classi, la documentazione permette agli IDE di aumentare le capacità di autocompletamento e di segnalare eventuali errori nelle chiamate di metodi, ad esempio perché è stato fornito un parametro del tipo sbagliato.
PHPDoc
Per rispondere a questa esigenza è nato uno standard informale per la documentazione delle classi inizialmente supportato solo da software per la generazione di documentazione come phpDocumentor e in seguito da vari IDE. Oggi esistono molte soluzioni per la generazione di documentazione che si differenziano per l'aspetto finale del risultato e, molto marginalmente, per le sintassi riconosciute.
Dal punto di vista pratico si tratta di un adattamento di Javadoc, sistema analogo per il linguaggio Java, e ogni direttiva PHPDoc deve essere inserita all'interno di un commento di tipo DocBlock. Un commento DocBlock si riferisce alla prima dichiarazione valida seguente dove per dichiarazione s'intende la definizione di una classe, la definizione di un metodo, la dichiarazione di una variabile, la definizione di una costante, etc. Fa eccezione il primo DocBlock che, se posizionato all'inizio del file, rappresenta una documentazione per l'intera pagina quando la prima dichiarazione successiva ha un proprio DocBlock, anche vuoto.
La sintassi generale di un commento DocBlock prevede l'apertura dello stesso con la sequenza /**
, la presenza di un carattere *
all'inizio di ogni riga seguente e la chiusura dell'intero blocco con */
. Ogni blocco è costituito da un commento valido per quanto riguarda il linguaggio di programmazione. All'interno del DocBlock è prevista la presenza di una descrizione breve, rappresentata dalla prima riga di testo (indicativamente della lunghezza di una linea di testo) e di una descrizione facoltativa più lunga separata dalla prima per mezzo di una riga vuota.
<?php
/**
* DocBlock riferito all'intera pagina.
*/
/**
* DocBlock riferito alla classe MyClass.
*
* Descrizione lunga della classe MyClass.
* In assenza di questo DocBlock il precedente
* sarebbe considerato associato a questa classe
* e non al file.
*/
class MyClass {}
Tag
Oltre alle semplici descrizioni testuali, molto utili per gli sviluppatori, ogni DocBlock può contenere un numero indefinito di tag. Ogni tag preceduto dal simbolo @
prevede una sintassi specifica e descrive una certa funzionalità della definizione a cui è associata.
Alcuni tag prevedono di specificare il tipo di parametro a cui si riferiscono scegliendolo tra una serie di valori:
Tag | Descrizione |
---|---|
@return |
Indica quello che deve restituire una funzione o un metodo, è necessario indicare solo il valore senza descrizione. |
@var |
Indica la tipologia di una proprietà di classe o di una variabile (ad esempio è possibile specificare il valore atteso per una variabile di un ciclo foreach in modo da godere dell'autocompletamento dell'IDE), è poi possibile aggiungere una descrizione. |
@const |
Indica la tipologia di una costante, insieme ad una descrizione. |
@param |
Indicare la tipologia di un parametro atteso da un metodo o da una funzione, è necessario indicare, oltre alla descrizione, il nome del parametro a cui il tag si riferisce. |
Tipologie di valori
I valori predefiniti disponibili sono:
Valore | Descrizione |
---|---|
int |
Numero intero. |
float |
Numero con decimali. |
string |
Stringa testuale. |
bool |
Valore booleano. |
object |
Indica che verrà accettato un oggetto di qualsiasi tipo. |
resource |
Risorsa definita da PHP come un file handler o una connessione ad un database. |
void |
Indica la mancanza di un valore restituito da una funzione (funzioni senza direttive return ). |
callable |
Indica un valore di tipo callable tra quelli supportati da PHP, quindi il nome di una funzione o di un metodo, una funzione anonima, un oggetto Closure .
|
Se il parametro accettato o restituito può essere di diversi tipi è possibile indicarlo con mixed
o elencare i tipi accettati separandoli con il carattere |
. In questo modo è possibile anche indicare che in alcuni casi una variabile può assumere il valore nullo in modo che lo sviluppatore sappia che può aspettarsi questo risultato indicandolo con il tipo null
.
Per i parametri di tipo array o per collezioni (che implementano le interfacce per le iterazioni) esiste una doppia sintassi: indicare il parametro facendo seguire al tipo contenuto all'interno dell'array i caratteri []
o indicare il nome della collezione e il suo contenuto all'interno di <
e >
. Di seguito le alternative valide:
<php
/**
* @var int[]
*/
$arrayOfIntegerValues = array(1, 2, 3, 4);
/**
* @var (int|string)[]
*/
$arrayOfIntegerOrStringValues = array(1, 'string', 3, 'another string');
/**
* @var mixed[]
*/
$arrayOfMixedValues = array('one string', 2, 'two string', new MyClass(), null);
/**
* @var MyCollection<float>
*/
$collectionOfFloatValues = (new MyCollection())->setValues(1.0, 2.5, 3.8, 4.6);
Per quanto riguarda i parametri di tipo oggetto, in aggiunta rispetto al tipo predefinito object
è possibile indicare il nome della classe di cui sono istanza eventualmente completa di namespace (fully qualified domain name).
Se si tratta di un parametro restituito è possibile usare i tipi predefiniti speciali:
Tipo | Descrizione |
---|---|
self |
Restituisce un oggetto del tipo della classe in cui è stato definito, lo sviluppatore e l'IDE non si aspettano la presenza di metodi implementati da classi che ereditano dalla classe madre e questo può portare ad errori o risultati non attesi. |
static |
Restituisce un oggetto del tipo della classe di cui è istanza l'oggetto creato. |
$this |
Restituisce non solo un oggetto della classe prevista da static ma la stessa istanza (utile in caso di interfacce fluenti). |