PHP – metodi magici __get e __set best practice

23 Dic

Out Of Date Warning

Questo post è stato pubblicato più di 2 anni fa (il 23 dicembre 2012). Le idee vanno avanti velocemente, le prospettive cambiano quindi i contenuti potrebbero non essere aggiornati. Ti prego di tenere in considerazione questo, e di verificare le informazioni tecniche presenti nell'articolo prima di farne affidamento per i tuoi scopi.

PHP dispone di un certo un mero di funzioni dette “metodi magici“. Si tratta di metodi che vengono attivati al verificarsi di terminati eventi, ed aventi una sintassi particolare nel nome. Difatti li possiamo riconoscere facilmente visto che iniziano tutti con un doppio undescore.

Due di questi (__construct e __destruct) li abbiamo già conosciuti in un mio precedente post: capire i costruttori ed i distruttori, mentre l’elenco completo lo potete trovare direttamente nella documentazione ufficiale: PHP Magic Methods.
In questo articolo voglio soffermarmi su un paio di metodi magici, cioè __get() e __set(), soprattutto dal punto di vista della loro utilità e possibilità di utilizzo nel “mondo reale”.

Come funzionano

Le funzioni __get, e __set naturalmente si riferiscono alla programmazione OOP, quindi devono essere dichiarate all’interno di una classe.
Questi metodi sono invocati quando la proprietà è inaccessibile (o non esiste, quindi è inaccessibile).

Nel codice precedente verrà invocato il metodo __get visto che la proprietà $baz anche se esiste è privata, quindi non accessibile direttamente dall’esterno.

Se $baz fosse stata pubblica allora il metodo non sarebbe stato invocato.
Stesso discorso per quanto riguarda __set, che sarà invocato quando si cerca di settare il valore di un attributo inaccessibile.

__get e __set come getter e setter

Bene ora che abbiamo capito cono funzionano, la domanda nasce spontanea. Può essere considerata una buona pratica utilizzare i metodi magici __get e __set come sostituti di dei canonici getter e setter?
Facciamo alcune considerazioni aiutandoci con qualche esempio.

Usando __get e __set

Lo snippet di codice precedente è piuttosto intuitivo, abbiamo usato i metodi magici per ottenere e settare i valori di proprietà non direttamente accessibili dall’esterno. Vediamo lo stesso esempio usando questa volta un approccio più tradizionale.

Usando i tradizionali getters e setters

La prima cosa da notare è che da entrambi gli esempi otterremo lo stesso identico risultato.
A prima vista la prima soluzione potrebbe apparire come la migliore o quantomeno quella più concisa e snella. Due metodi contro quattro (che aumenterebbero con l’aumentare delle proprietà).
Tuttavia ci non diversi aspetti negativi e pericolosi da considerare:

  • __get e __set sono decisamente più lenti (fino a 10 volte) di getter / setter
  • Rendono impossibile il completamento automatico del codice e questo è un grave problema (personalmente non conosco un IDE che sia in grado di farlo).
  • Le APIs risultano poco chiare.
  • Il sistema è più difficile da capire, soprattutto per i nuovi arrivati.

Considerazioni finali

I metodi magici non sono sostituti di getter e setter. Come spiegato consentono di gestire le chiamate a proprietà inaccessibili che altrimenti causerebbero un errore. Quindi a mio avviso sono da considerarsi più legati alla gestione degli errori che altro.

Nel caso in cui, tuttavia, scegliessimo si utilizzare __get e __set come getter e setter questo non è un errore, ma solamente, almeno dal mio punto di vista, una cattiva pratica.
In questo caso è raccomandato utilizzare un array:

In questo modo siamo sicuri che non è possibile accedere alla variabile in un’altro modo per evitare collisioni (notare che $_value è protetta).

2 Commenti su “PHP – metodi magici __get e __set best practice”

  1. Unk 20 dicembre 2013 at 00:19 #

    Ottimo articolo, chiaro e conciso.

  2. Lillian 17 luglio 2016 at 18:43 #

    Simply wish to say your article is as amazing.
    The clearness for your submit is just excellent and i could suppose you’re a
    professional on this subject. Fine with your permission let me
    to clutch your RSS feed to keep updated with approaching post.
    Thanks one million and please carry on the enjoyable work.

Lascia un commento