Sul Web ci sono molte informazioni datate che portano gli utenti PHP fuori strada, propagando cattive abitudini e codice non sicuro. PHP: La Retta Via è una guida di riferimento veloce e facile da leggere contenente le migliori tecniche di sviluppo PHP, gli standard popolari di scrittura del codice, link a tutorial autorevoli sparsi per il Web e quelle che secondo gli autori sono attualmente le migliori pratiche.
Non c’è un solo modo corretto di usare PHP. Questo sito Web mira a presentare ai nuovi sviluppatori PHP alcuni argomenti che potrebbero non prendere mai in considerazione, se non troppo tardi, e mira a fornire ai professionisti alcune idee fresche riguardo procedure che hanno usato per anni senza mai aggiornarle. Questo sito Web inoltre non ti dirà mai quali strumenti usare, ma invece offrirà suggerimenti per opzioni multiple, spiegando le differenze nell’approccio e nei casi di utilizzo.
Questo è un documento in sviluppo e continuerà a essere aggiornato con nuove informazioni utili ed esempi non appena saranno disponibili.
PHP: La Retta Via è tradotto in molte lingue diverse:
Aiuta questo sito Web a diventare la migliore risorsa per i nuovi programmatori PHP! Contribuisci su GitHub
PHP: La Retta Via ha immagini banner che puoi usare sul tuo sito Web. Mostra il tuo supporto e fai sapere ai nuovi sviluppatori PHP dove possono trovare buone informazioni.
Se hai appena iniziato con PHP, assicurati di usare l’ultima versione stabile di PHP 7.0. Il team di PHP ha aggiunto nuove potenti funzionalità rispetto alle vecchie versioni del ramo 5.x.
Potresti trovarti a usare ancora, nel prossimo futuro, PHP 5.x, la cui ultima versione è 5.6. Non è una cattiva opzione, ma dovresti provare ad aggiornare presto all’ultima versione stabile, perché PHP 5.6 non riceverà aggiornamenti di sicurezza dopo il 2018. L’aggiornamento è molto facile, non ci sono molte incompatibilità. Se non sei sicuro della versione o delle funzionalità presenti, verifica la documentazione sul sito php.net.
Con PHP 5.4 o successivo, puoi iniziare a studiare PHP senza installare e configurare un web server completo. Per avviare il server, esegui il seguente comando dal terminale nella web root del tuo progetto:
OS X viene fornito con una versione pre-pacchettizzata di PHP, ma è normalmente un po’ più vecchia dell’ultima versione stabile. Mountain Lion ha la 5.3.10, Mavericks ha la 5.4.17 e Yosemite ha la 5.5.9, ma con PHP 5.6 già rilasciato di solito non è abbastanza.
Ci sono diversi modi per installare PHP su OS X.
Homebrew è un potente gestore di pacchetti per OS X che può aiutarti a installare facilmente PHP e varie estensioni. Homebrew PHP è un repository che contiene “formule” per Homebrew relative a PHP e ti permetterà di installare PHP.
A questo punto, puoi installare php53
, php54
, php55
o php56
usando il
comando brew install
e cambiando la versione attiva modificando la variabile
PATH
.
Il progetto MacPorts è un’iniziativa della comunità open source per il design di un sistema di semplice utilizzo per la compilazione, l’installazione e l’aggiornamento di software open source per linea di comando, X11 o Acqua sul sistema operativo OS X.
MacPorts supporta i binari precompilati, quindi non devi ricompilare le dipendenze dai sorgenti ogni volta. È un salvavita se non hai alcun pacchetto installato sul sistema.
In questo momento puoi installare php53
, php54
, php55
o php56
usando il
comando port install
. Per esempio:
sudo port install php54
sudo port install php55
E puoi eseguire il comando select
per cambiare la versione attiva di PHP:
sudo port select --set php php55
phpbrew è uno strumento per l’installazione e la gestione di versioni multiple di PHP. Può essere molto utile se due applicazioni/progetti differenti richiedono versioni differenti di PHP e non stai usando le macchine virtuali.
Un’altra opzione che ti fornisce controllo sulla versione di PHP che installi è compilarlo tu stesso. In questo caso assicurati di avere installato Xcode o il sostituto di Apple “Strumenti da riga di comando per XCode”, scaricabile dal Centro Sviluppatori Mac di Apple.
Le soluzioni elencate sopra gestiscono principalmente solo PHP, e non forniscono cose come Apache, Nginx o un server SQL. Le soluzioni “all-in-one” come MAMP e XAMPP installeranno questi altri software per te e li integreranno l’uno con l’altro, ma la facilità d’installazione compromette la flessibilità.
Puoi installare PHP su Windows in diversi modi. Puoi scaricare i binari e, fino a poco tempo fa, potevi usare un installer ‘.msi’. L’installer non è più disponibile e si ferma a PHP 5.3.0.
Per l’apprendimento e lo sviluppo locale puoi usare il webserver integrato in PHP 5.4 e superiori, in modo da non doverlo configurare. Se preferisci un pacchetto “all-in-one” che include un webserver e MySQL, allora strumenti come Web Platform Installer, [Zend Server CE][zsce], XAMPP e WAMP ti aiuteranno a configurare un ambiente di sviluppo Windows in men che non si dica. Detto questo, questi strumenti saranno diversi dall’ambiente di produzione, quindi fai attenzione alle differenze se stai sviluppando su Windows ma pubblicando su Linux.
Se devi far girare un ambiente di produzione su Windows, allora IIS7 ti fornirà quello più stabile e performante. Puoi usare phpmanager (un plugin GUI per IIS7) per rendere più semplice la configurazione e la gestione di PHP. IIS7 integra già FastCGI, devi solo configurare PHP come handler. Per supporto e ulteriori informazioni, c’è un’area dedicata a PHP su iis.net.
La comunità PHP è grande e diversificata, fatta di innumerevoli librerie, framework e componenti. È comune per gli sviluppatori PHP scegliere diversi di questi e combinarli in un singolo progetto. È importante che il codice PHP aderisca (il più fedelmente possibile) a uno stile di codifica comune per rendere facile agli sviluppatori mischiare e usare diverse librerie nei loro progetti.
Il Framework Interop Group ha proposto e approvato una serie di raccomandazioni di stile. Non tutte riguardano lo stile del codice, ma quelle che lo riguardano sono note come PSR-0, PSR-1, PSR-2 e PSR-4. Queste raccomandazioni non sono che una lista di regole che alcuni progetti come Drupal, Zend, Symfony, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium etc. stanno iniziando ad adottare. Puoi usarle in uno dei tuoi progetti, o continuare a usare il tuo stile personale.
Idealmente dovresti scrivere codice PHP che aderisce ad uno standard noto. Può essere una qualunque combinazione dei PSR o uno degli standard di codifica di PHP o Zend. Questo significa che altri sviluppatori potranno facilmente leggere e lavorare col tuo codice, e le applicazioni che implementano i componenti potranno essere consistenti anche quando lavorano con molto codice di terze parti.
Puoi usare PHP_CodeSniffer per controllare che il codice rispetti queste raccomandazioni, e plugin per editor di testo come Sublime Text 2 per avere feedback in tempo reale.
Puoi sistemare la disposizione del codice automaticamente usando uno dei due strumenti disponibili. Uno è il PHP Coding Standards Fixer di Fabien Potencier, testato scrupolosamente. È più grande e più lento, ma molto stabile e usato da alcuni grandi progetti come Magento e Symfony. Un’altra opzione è php.tools, reso popolare dal plugin per editor [sublime-phpfmt][sublime-phpmft]. Nonostante sia nuovo, porta molti miglioramenti sotto il punto di vista della performance, quindi l’adattamento in tempo reale nell’editor è più fluido.
La lingua inglese è preferita per tutti i nomi di simboli e infrastrutture del codice. I commenti possono essere scritti in qualunque lingua facilmente comprensibile da tutte le parti presenti e future che dovranno lavorare sul codice.
PHP è un linguaggio flessibile e dinamico che supporta diverse tecniche di programmazione. Si è evoluto moltissimo negli ultimi anni, in particolare aggiungendo un solido modello a oggetti in PHP 5.0 (2004), le funzioni anonime e i namespace in PHP 5.3 (2009) e i trait in PHP 5.4 (2012).
PHP ha un set molto completo di funzionalità riguardanti la programmazione orientata agli oggetti inclusi il supporto per le classi, le classi astratte, le interfacce, l’ereditarietà, i costruttori, la clonazione, le eccezioni e altro.
PHP supporta le funzioni di prima classe, il che significa che una funzione può essere assegnata a una variabile. Ci si può riferire tramite variabili sia alle funzioni definite dall’utente che a quelle native, ed entrambe possono essere invocate dinamicamente. Le funzioni possono essere passate ad altre funzioni come argomenti (caratteristica chiamata Funzioni di ordine superiore) e le funzioni possono restituire altre funzioni.
La ricorsione, una caratteristica che permette a una funzione di chiamare se stessa, è supportata dal linguaggio, ma la maggior parte del codice PHP è incentrato sull’iterazione.
Le nuove funzioni anonime (con supporto per le chiusure) esistono da PHP 5.3 (2009).
PHP 5.4 ha aggiunto la possibilità di legare le chiusure allo scope di un oggetto e ha migliorato il supporto per i callback in modo che possano essere usati quasi sempre in modo intercambiabile con le funzioni anonime.
call_user_func_array
PHP supporta varie forme di metaprogrammazione tramite meccanismi come la
Reflection API e i metodi magici. Ci sono diversi metodi magici disponibili come
__get()
, __set()
, __clone()
, __toString()
, __invoke()
etc. che
permettono agli sviluppatori di modificare il funzionamento di una classe. Gli
sviluppatori Ruby dicono spesso che a PHP manca il metodo method_missing
, ma è
disponibile sotto il nome di __call()
e __callStatic()
.
Come menzionato sopra, la comunità PHP ha molti sviluppatori che creano molto codice. Questo significa che il codice PHP di una libreria potrebbe usare lo stesso nome di un’altra per una classe. Quando entrambe le librerie vengono usate nello stesso namespace, potrebbero collidere e causare problemi.
I namespace risolvono questo problema. Come descritto nel manuale di PHP, si può pensare ai namespace come directory del sistema operativo che dividono i file; due file con lo stesso nome possono esistere in directory separate. Allo stesso modo, due classi PHP con lo stesso nome possono esistere in namespace PHP separati. È così semplice.
È importante inserire il codice in un namespace in modo che possa essere usato da altri sviluppatori senza paura che esso collida con altre librerie.
Nel dicembre 2013 il PHP-FIG ha creato un nuovo standard per l’autoloading: PSR-4, che un giorno probabilmente rimpiazzerà PSR-0. Attualmente entrambi sono ancora utilizzabili, perché PSR-4 richiede PHP 5.3 e molti progetti che supportano solo PHP 5.2 attualmente implementano PSR-0. Se userai un autoloader standard per una nuova applicazione o pacchetto allora vorrai quasi sicuramente dare un’occhiata a PSR-4.
Un modo raccomandato di usare i namespace è delineato nel [PSR-4], che mira a fornire una convenzione standard per la i nomi di file, classi e namespace, in modo da consentire la scrittura di codice plug-and-play.
Nell’ottobre 2014 il PHP-FIG ha deprecato il precedente standard di autoloading, PSR-0, che è stato sostituito con PSR-4. Attualmente entrambi sono ancora utilizzabili, giacché PSR-4 richiede PHP 5.3 e molti progetti solo per PHP 5.2 implementano attualmente PSR-0. Se hai intenzione di usare uno standard di autoloading per una nuova applicazione o pacchetto, probabilmente PSR-4 è la scelta giusta.
La Standard PHP Library (SPL) è distribuita con PHP e fornisce un insieme di classi e interfacce. È fatta principalmente di strutture di dati di uso comune (pile, code, cumuli etc.) e iteratori che possono navigare attraverso queste strutture o attraverso le tue classi che implementano le interfacce SPL.
PHP è stato creato per scrivere applicazioni Web, ma è anche utile nella creazione di programmi da linea di comando (CLI). I programmi da linea di comando aiutano ad automatizzare compiti come il testing, la pubblicazione e l’amministrazione dell’applicazione.
I programmi PHP CLI sono potenti perché puoi usare il codice della tua applicazione direttamente, senza dover creare una GUI sicura. Accertati solo di non mettere gli script CLI nella root pubblica!
Prova ad eseguire PHP dalla tua linea di comando:
L’opzione -i
visualizzerà la tua configurazione PHP proprio come la funzione
phpinfo
.
L’opzione -a
fornisce una shell interattiva, simile all’IRB di Ruby o alla
shell interattiva di Python. Ci sono anche altre opzioni utili.
Scriviamo un semplice programma “Hello, $name”. Per provarlo, crea un file
chiamato hello.php
come nell’esempio.
PHP imposta due variabili speciali a seconda degli argomenti con cui viene
eseguito il tuo script. $argc
è una variabile intera contenente il
numero degli argomenti e $argv
è un array contenente il valore di
ciascun argomento. Il primo argomento è sempre il nome del tuo file PHP, in
questo caso hello.php
.
L’espressione exit()
è usata con un numero diverso da zero per far sapere alla
shell che l’esecuzione del comando è fallita. Codici di uscita comunemente usati
possono essere trovati qui.
Per eseguire lo script sopra dalla linea di comando:
Uno degli strumenti più utili nello sviluppo software è un buon debugger. Ti permette di tracciare l’esecuzione del codice e monitorare i contenuti dello stack. Xdebug, il debugger di PHP, può essere utilizzato da diversi IDE per fornire punti di interruzione e ispezioni dello stack. Può anche permettere a strumenti come PHPUnit e KCacheGrind di eseguire analisi della copertura del codice e di profilatura.
Se ti trovi con le mani legate e utilizzando var_dump
/print_r
non riesci
ancora a trovare la soluzione, forse devi usare il debugger.
L’installazione di XDebug può essere complessa, ma una delle sue funzioni più importanti è il debug da remoto. Se sviluppi codice localmente e lo testi in una macchina virtuale o su un altro server, il debug da remoto è la funzione che dovresti abilitare immediatamente.
Solitamente dovrai modificare il tuo virtual host o file .htaccess con questi valori:
L’opzione remote_host
e remote_port
corrispondono al tuo computer locale e
alla porta su cui fai ascoltare l’IDE. A questo punto si tratta solo di mettere
l’IDE in modalità di ascolto e caricare l’URL:
http://tuo-sito.example.com/index.php?XDEBUG_SESSION_START=1
Il tuo IDE intercetterà lo stato attuale durante l’esecuzione dello script, permettendoti di impostare punti di interruzione e ispezionare i valori in memoria.
I debugger grafici rendono molto semplice navigare nel codice, ispezionare variabili ed eseguire codice nel runtime attivo. Molti IDE hanno il supporto integrato o tramite plugin per il debugging grafico tramite Xdebug. MacGBDp è una GUI per Xdebug gratuita, open-source e stand-alone dedicata al Mac.
Ci sono moltissime librerie PHP, framework e componenti tra cui scegliere. Il tuo progetto, probabilmente, ne userà diversi. Queste sono dipendenze del progetto. Fino a poco tempo fa, PHP non aveva un buon modo per gestire le dipendenze del progetto. Anche se le gestivi manualmente, dovevi comunque preoccuparti degli autoloader. Non più.
Attualmente ci sono due grandi sistemi di gestione dei pacchetti per PHP: Composer e PEAR. Composer è il gestore di pacchetti principale per PHP, ma per lungo tempo PEAR ha ricoperto quel ruolo. Sapere cos’è PEAR è una buona idea perché potresti trovare diversi riferimenti a esso, anche se non lo userai mai.
Composer è un ottimo gestore delle dipendenze per PHP. Elenca le dipendenze
del tuo progetto in un file composer.json
e, con pochi semplici comandi,
Composer scaricherà automaticamente le dipendenze e imposterà l’autoloading al
posto tuo.
Ci sono già molte librerie PHP che sono compatibili con Composer pronte per essere usate nel tuo progetto. Questi “pacchetti” sono elencati su Packagist, il repository ufficiale per le librerie PHP disponibili tramite Composer.
Puoi installare Composer localmente (nella tua directory di lavoro; ma questo non è più consigliato) o globalmente (es. /usr/local/bin). Supponiamo tu lo voglia installare localmente. Dalla directory root del tuo progetto:
Questo scaricherà composer.phar
(un archivio PHP binario). Puoi eseguirlo con
php
per gestire le dipendenze del tuo progetto. Attenzione:
se esegui direttamente del codice proveniente dal Web, controllalo online per
assicurarti che sia sicuro.
Per gli utenti Windows il modo più facile di configurare tutto è usare
l’installer [ComposerSetup][6], che esegue un’installazione globale e imposta la
variabile $PATH
in modo che si possa chiamare composer
nella linea di
comando da qualunque directory.
L’installazione manuale di Composer è una tecnica avanzata; tuttavia, ci sono diverse ragioni per cui uno sviluppatore potrebbe preferire questo metodo rispetto alla procedura di installazione interattiva. L’installazione interattiva controlla la tua versione di PHP per assicurarsi che:
.phar
possano essere eseguiti correttamentephp.ini
Poiché un’installazione manuale non esegue alcuno di questi controlli, dovrai decidere se il lavoro vale la pena. Ecco come installare Composer manualmente:
La directory $HOME/local/bin
(o una directory di tua scelta) dovrebbe essere
nella variabile di ambiente $PATH
. In questo modo il comando composer
sarà
disponibile.
Quando incontri documentazione che dice di eseguire Composer con php
composer.phar install
, puoi sostituirlo con:
Questa sezione presumerà che tu abbia installato composer globalmente.
Composer tiene traccia delle dipendenze del tuo progetto in un file chiamato
composer.json
. Puoi gestirlo manualmente se preferisci, o usare lo stesso
Composer. Il comando composer require
aggiunge una dipendenza del progetto e,
se non hai un file composer.json
, lo crea. Ecco un esempio che aggiunge
Twig come dipendenza del tuo progetto:
In alternativa puoi usare il comando composer init
, che ti guiderà nella
creazione di un file composer.json
per il tuo progetto. In ogni caso, una
volta che hai creato il file composer.json
, puoi dire a Composer di scaricare
e installare le dipendenze nella cartella vendors/
. Questo vale anche per i
progetti che hai scaricato e che forniscono un file composer.json
:
Adesso, aggiungi questa linea al file principale della tua applicazione PHP; questo dirà a PHP di usare l’autoloader di Composer per le dipendenze del tuo progetto.
Ora puoi usare le dipendenze del tuo progetto, che saranno caricate automaticamente quando richieste.
Composer crea un file chiamato composer.lock
che contiene la versione esatta
di ogni pacchetto che ha scaricato durante l’esecuzione di php composer.phar
install
. Se condividi il tuo progetto con altre persone e il file
composer.lock
è parte della distribuzione, quando eseguiranno php
composer.phar install
otterranno le tue stesse versioni. Per aggiornare le
dipendenze, esegui php composer.phar update
.
Questo è particolarmente utile quando definisci i tuoi requisiti di versione in
maniera flessibile. Per esempio, un requisito di ~1.8
significa “qualunque
versione dopo la 1.8.0
, ma minore di 2.0.x-dev
”. Puoi anche usare il
carattere jolly *
(es. 1.8.*
). Ora il comando di Composer php composer.phar
update
aggiornerà le dipendenze alla versione più recente che soddisfa i
requisiti definiti.
Per ricevere notifiche riguardo release di nuove versioni puoi registrati a
VersionEye, un servizio web che può monitorare i tuoi account GitHub e
BitBucket alla ricerca di file composer.json
e mandare email con le nuove
release dei pacchetti.
Il Security Advisories Checker è un web service e uno strumento da linea di
comando. Entrambi esamineranno il file composer.lock
e ti diranno se devi
aggiornare le tue dipendenze.
Composer può anche gestire le dipendenze globali e i loro binari. L’uso è
semplice, tutto quello che devi fare è aggiungere il prefisso global
al
comando. Se per esempio volessi installare PHPUnit globalmente, eseguiresti il
seguente comando:
Questo creerà una cartella ~/.composer
contenente le tue dipendenze globali.
Per rendere disponibili ovunque i binari dei pacchetti, dovrai solo aggiungere
la cartella ~/.composer/vendor/bin
alla tua variabile $PATH
.
Un altro gestore di pacchetti storico che molti sviluppatori PHP amano è PEAR. Si comporta più o meno come Composer, ma presenta alcune differenze che è bene conoscere.
PEAR richiede che ogni pacchetto abbia una struttura specifica, il che significa che l’autore del pacchetto deve prepararlo per l’utilizzo con PEAR. Usare un progetto che non è stato preparato per l’utilizzo con PEAR non è possibile.
PEAR installa i pacchetti globalmente, il che significa che dopo la prima installazione essi diventano disponibili per tutti i progetti su quel server. Questa può essere una buona cosa se molti progetti utilizzano la stessa versione dello stesso pacchetto, ma può portare a problemi se si creano conflitti di versione tra due progetti.
Puoi installare PEAR scaricando l’installer .phar
ed eseguendolo. La
documentazione di PEAR ha istruzioni d’installazione dettagliate per ogni
sistema operativo.
Se stai usando Linux, puoi anche dare un’occhiata al gestore di pacchetti della
tua distribuzione. Debian e Ubuntu, per esempio, hanno un pacchetto APT
php-pear
.
Se un pacchetto è elencato nella lista di pacchetti PEAR, puoi installarlo specificando il suo nome ufficiale:
Se il pacchetto è hostato su un altro canale, dovrai prima scoprire il canale e specificarlo durante l’installazione. Vedi la documentazione sull’uso dei canali per più informazioni su questo argomento.
Se stai già usando Composer e vorresti installare del codice PEAR, puoi
usare Composer per gestire le tue dipendenze PEAR. Questo esempio installerà
codice da pear2.php.net
:
La prima sezione "repositories"
verrà usata per far sapere a Composer che deve
“inizializzare” (o “scoprire” nella terminologia PEAR) il repository PEAR. Poi
nella sezione require viene aggiunto un prefisso al nome del pacchetto, così:
> pear-channel/Package
Il prefisso “pear” è fisso per evitare conflitti, poiché un canale PEAR potrebbe essere identico al nome del distributore di altri pacchetti. In questo modo il nome del canale (o l’URL completo) può essere usato per riferirsi al canale in cui si trova il pacchetto.
Il codice installato viene messo nella directory vendors/
ed è automaticamente
disponibile tramite l’autoloader di Composer:
vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php
Per usare questo pacchetto PEAR scrivi semplicemente:
PHP è un linguaggio vasto che permette a programmatori di ogni livello di produrre codice non solo velocemente, ma efficientemente. Tuttavia, avanzando nell’apprendimento del linguaggio, ci scordiamo spesso le basi che abbiamo imparato (o su cui abbiamo sorvolato) in favore di scorciatoie e/o cattive pratiche. Per aiutare a combattere questo male comune, questa sezione mira a ricordare ai programmatori delle pratiche di codifica di base in PHP.
PHP ha una classe chiamata DateTime che aiuta nella lettura, scrittura, confronto e calcolo di date e ore. Non ci sono molte funzioni relative alle date e all’ora in PHP a parte DateTime, ma essa fornisce una interfaccia orientata agli oggetti ai casi di uso più comuni. Può gestire i fusi orari, ma ciò esula da questa breve introduzione.
Per iniziare a lavorare con DateTime, converti le rappresentazioni grezze di
date e ora in un oggetto con il metodo createFromFormat()
o esegui
new \DateTime
per ottenere la data e l’ora attuali. Usa il metodo format()
per convertire DateTime in una stringa da visualizzare.
Il calcolo con DateTime è possibile grazie alla classe DateInterval. DateTime ha
dei metodi come add()
e sub()
che prendono un DateInterval per argomento.
Non scrivere codice che presume ci sia lo stesso numero di secondi in ogni
giorno, sia l’ora legale che i cambiamenti nel fuso orario altereranno i
risultati. Invece usa gli intervalli di data. Per calcolare la differenza tra
date usa il metodo diff()
. Restituirà un nuovo DateInterval, che è molto
facile da visualizzare.
Sugli oggetti DateTime è possibile eseguire un confronto standard:
Un ultimo esempio per dimostrare l’utilizzo della classe DatePeriod. Viene usata per iterare su eventi ricorrenti. Può prendere due oggetti DateTime, inizio e fine, e l’intervallo per il quale restituirà tutti gli eventi compresi.
Quando stai costruendo la tua applicazione è d’aiuto usare dei pattern di progettazione del tuo codice e pattern comuni per la struttura complessiva del tuo progetto. Usare pattern comuni è utile perché rende molto più facile gestire il tuo codice e permette ad altri sviluppatori di capire velocemente come tutti i componenti lavorano tra loro.
Se usi un framework la maggior parte del codice di alto livello e la struttura del tuo progetto saranno basati su quel framework, quindi molte delle decisioni riguardanti i pattern vengono fatte al posto tuo. Ma è comunque una tua scelta quella dei migliori pattern da seguire nel codice che crei appoggiandoti a quel framework. Se, d’altra parte, non stai usando un framework per creare la tua applicazione allora dovrai trovare i pattern che si adattano meglio al tipo e alle dimensioni dell’applicazione che stai costruendo.
Questa sezione è stata originariamente scritta da Alex Cabal su PHP Best Practices ed è stata usata come base per i nostri consigli su UTF-8.
Attualmente PHP non supporta Unicode al basso livello. Ci sono dei modi per assicurarsi che le stringhe UTF-8 vengano processate correttamente, ma non è semplice, ed è necessario scavare in quasi tutti i livelli dell’applicazione web, dall’HTML all’SQL al PHP. Cercheremo di scrivere un sommario breve e pratico.
Le operazioni di base con le stringhe, come il concatenamento di due stringhe e
l’assegnamento di stringhe a variabili, non richiedono nulla di speciale per il
supporto UTF-8. Tuttavia la maggior parte delle funzioni per le stringhe, come
strpos()
e strlen()
, richiedono particolare considerazione. Queste funzioni
hanno solitamente una controparte mb_*
: per esempio, mb_strpos()
e
mb_strlen()
. Queste stringhe mb_*
vengono fornite tramite l’Estensione
Multibyte String, e sono specificatamente disegnate per operare su stringhe
Unicode.
Devi usare le funzioni mb_*
ogni qualvolta operi su una stringa Unicode. Per
esempio, se usi substr()
su una stringa UTF-8, c’è una buona possibilità che
il risultato includa dei caratteri incomprensibili. La funzione corretta da
usare sarebbe la controparte multibyte, mb_substr()
.
La parte difficile è ricordarsi di usare le funzioni mb_*
ogni volta. Se ti
dimentichi anche una sola volta, la tua stringa Unicode rischia di divenire
incomprensibile durante le operazioni successive.
Non tutte le funzioni per le stringhe hanno una controparte mb_*
. Se non ce
n’è una per quello che vuoi fare, allora peggio per te.
Inoltre, dovresti usare la funzione mb_internal_encoding()
all’inizio di ogni
script PHP che scrivi (o in cima al tuo script incluso globalmente), e la
funzione mb_http_output()
subito dopo se il tuo script invia dati a un
browser. Definire esplicitamente la codifica delle tue stringhe in ogni script
ti salverà molti futuri mal di testa.
Infine, molte funzioni PHP che operano sulle stringhe hanno un parametro
opzionale che ti permette di specificare la codifica dei caratteri. Dovresti
sempre esplicitamente indicare UTF-8 quando ne hai la possibilità. Per esempio,
htmlentities()
ha un’opzione per la codifica dei caratteri, e dovresti sempre
specificare UTF-8 se hai a che fare con certe stringhe. Tieni a mente che, a
partire da PHP 5.4.0, UTF-8 è la codifica predefinita per htmlentities()
e
htmlspecialchars()
.
Infine, se stai costruendo un’applicazione distribuita e non sei certo che
l’estensione mbstring
sarà disponibile, considera l’idea di usare il pacchetto
Composer patchwork/utf8. Questo userà mbstring
se è disponibile, e le
funzioni non UTF-8 se non lo è.
Se il tuo script PHP accede a MySQL, è possibile che le tue stringhe vengano salvate nel database come stringhe non UTF-8 anche se segui tutte le precauzioni di cui sopra.
Per assicurarti che le tue stringhe vadano da PHP a MySQL come UTF-8, assicurati
che il set e la collation di caratteri del tuo database e delle tue tabelle
siano impostati a utf8mb4
, e usa il set di caratteri utf8mb4
nella stringa
di connessione PDO. Vedi l’esempio di codice sotto. Questo è estremamente
importante.
Tieni a mente che devi usare il set di caratteri utf8mb4
per il supporto
completo a UTF-8, non il set di caratteri utf8
! Vedi Ulteriori letture per
scoprire perché.
Usa la funzione mb_http_output()
per assicurarti che il tuo script PHP invii
stringhe UTF-8 al tuo browser.
Il browser avrà poi bisogno di sapere dalla risposta HTTP che questa pagina
dev’essere considerata come UTF-8. L’approccio storico è usare il <meta>
tag
charset nel tag <head>
della
tua pagina. Questo approccio è perfettamente valido, ma impostare il charset
nell’header Content-Type
è in realtà
molto più veloce.
Da Wikipedia:
L’iniezione delle dipendenze è un design pattern della programmazione software che permette la rimozione di dipendenze cablate a codice e rende possibile cambiarle, durante l’esecuzione o la compilazione.
Questa citazione fa sembrare il concetto molto più complicato di quanto sia in realtà. L’iniezione delle dipendenze consiste nel fornire a un componente le sue dipendenze tramite l’iniezione nel costruttore, chiamate a metodi, o l’impostazione di proprietà. Tutto qui.
Possiamo dimostrare il concetto con un esempio semplice ma primitivo.
Abbiamo una classe Database
che richiede un adattatore per comunicare col
database. Istanziamo un adattatore nel costruttore e creiamo una dipendenza
cablata a codice. Questo rende il testing difficoltoso e la classe Database
fortemente legata all’adattatore.
Questo codice può essere rifattorizzato in modo che usi l’iniezione delle dipendenze, e dunque renda la dipendenza più elastica.
Ora forniamo alla classe Database
la sua dipendenza invece di crearla noi.
Potremmo anche creare un metodo che accetti un argomento della dipendenza e
impostarla così, o se la proprietà $adapter
fosse public
potremmo impostarla
direttamente.
Se hai mai letto qualcosa sull’iniezione delle dipendenze allora hai probabilmente visto i termini “Inversione del controllo” o “Principio di inversione della dipendenza”. Questi sono problemi complessi risolti dall’iniezione delle dipendenze.
L’inversione del controllo consiste, come suggerisce il nome, nell’“invertire il controllo” di un sistema tenendo il controllo organizzativo completamente separato dai nostri oggetti. Con l’iniezione delle dipendenze, questo significa rendere le dipendenze più flessibili controllandole e istanziandole in un altro punto del sistema.
Per anni, i framework PHP hanno usato l’inversione del controllo. Tuttavia, la domanda è diventata: quale parte del controllo stai invertendo, e dove? Per esempio, i framework MVC generalmente fornivano un oggetto padre o un controller di base che gli altri controller dovevano estendere per accedere alle sue dipendenze. Questa è inversione del controllo, ma invece di rendere le dipendenze più flessibili, questo metodo semplicemente le spostava.
L’iniezione delle dipendenze ci permette di risolvere questo problema in maniera più elegante, iniettando solo le dipendenze che ci servono, quando ci servono, senza il bisogno di alcuna dipendenza rigida.
Il principio di inversione della dipendenza è la “D” nell’insieme di principi di design orientato agli oggetti S.O.L.I.D., secondo cui si dovrebbe “Dipendere dalle astrazioni. Non dipendere dalle concrezioni.” Detto semplicemente, questo significa che le nostre dipendenze dovrebbero essere interfacce/contratti o classi astratte, non implementazioni concrete. Possiamo facilmente rifattorizzare l’esempio sopra in modo che segua questo principio.
Ci sono diversi benefici all’approccio seguito, in cui la classe Database
dipende ora da un’interfaccia piuttosto che da un’implementazione concreta.
Pensa di lavorare in team, e che un collega stia lavorando all’adattatore. Nel nostro primo esempio, avremmo dovuto aspettare che tale collega finisse l’adattore prima di poterlo imitare appropriatamente per i nostri unit test. Ora che la dipendenza è un’interfaccia/contratto, possiamo felicemente imitare quell’interfaccia sapendo che il nostro collega costruirà l’adattatore basandosi su quel contratto.
Un beneficio ancora più grande è che ora il nostro codice è molto più scalabile. Se tra un anno decidiamo che vogliamo migrare verso un tipo diverso di database, possiamo scrivere un adattatore che implementi l’interfaccia originale e iniettare quello. Non servirebbe alcun’altra rifattorizzazione, perché saremmo sicuri che l’adattore segue il contratto stabilito dall’interfaccia.
La prima cosa che dovresti capire riguardo i contenitori di iniezione delle dipendenze è che non sono uguali all’iniezione delle dipendenze. Un contenitore è un’utilità che ti aiuta a implementare l’iniezione delle dipendenze. Tuttavia, possono essere (e spesso sono) usati male per implementare un anti-pattern, la localizzazione dei servizi. Iniettare nelle tue classi un contenitore DI come un localizzatore di servizi crea una dipendenza dal contenitore ancora più forte di quella che stai sostituendo. Inoltre rende il tuo codice molto meno trasparente e più difficile da testare.
La maggior parte dei framework moderni ha il proprio contenitore di iniezione delle dipendenze che ti permette di unire insieme le dipendenze tramite configurazione. Questo significa che puoi scrivere del codice applicativo pulito e indipendente quanto il framework su cui è basato.
Molte volte il tuo codice PHP utilizzerà un database per memorizzare informazioni. Hai diverse opzioni per connetterti e interagire con il tuo database. L’opzione consigliata fino a PHP 5.1.0 era di usare i driver nativi come mysqli, pgsql, mssql etc.
I driver nativi vanno bene se usi un database nella tua applicazione ma se, per esempio, stai usando MySQL e un po’ di MSSQL, o devi connetterti a un database Oracle, allora non potrai usare gli stessi driver. Dovrai imparare una nuova API per ogni database e può diventare faticoso.
L’estensione mysql per PHP non è più attivamente sviluppata ed è
ufficialmente deprecata a partire da PHP 5.5.0, il che
significa che sarà rimossa nei prossimi rilasci. Se nelle tue applicazioni stai
usando delle funzioni che iniziano con mysql_*
come mysql_connect()
o
mysql_query()
, sappi che nelle versioni successive semplicemente non saranno
più disponibili. Questo significa che sarai obbligato a riscrivere il tuo codice
a un certo punto, quindi l’opzione migliore è rimpiazzare mysql con mysqli o
PDO secondo la tua tabella di marcia; in questo modo dopo non dovrai farlo in
fretta e furia.
Se stai iniziando ora, non usare assolutamente l’estensione mysql: usa l’estensione MySQLi o PDO.
PDO è una libreria di astrazione della connessione al database (integrata in PHP a partire dalla versione 5.1.0) che fornisce un’interfaccia comune per la comunicazione con molti database differenti. Per esempio, puoi usare praticamente lo stesso codice per interfacciarti con MySQL o SQLite:
PDO non tradurrà le tue query SQL e non emulerà le funzionalità mancanti; viene usato solo per connettersi a diversi tipi di database con la stessa API.
Ancora più importante, PDO ti permette di inserire in maniera sicura dell’input esterno (es. ID) nelle tue query SQL senza preoccuparti di attacchi di tipo SQL injection. È possibile farlo grazie agli statement e ai bound parameters di PDO.
Supponiamo che uno script PHP riceva un ID numerico come parametro della query. Questo ID dovrebbe essere usato per recuperare il record di un utente dal database. Ecco il modo sbagliato di farlo:
Questo codice è terribile. Stai inserendo direttamente un parametro della query
in una query SQL. Questa vulnerabilità sarà sfruttata in un batter d’occhio,
usando una pratica chiamata SQL Injection. Immagina solo cosa accadrebbe se un
hacker passasse un parametro id
fittizio chiamadno un URL come
http://domain.com/?id=1%3BDELETE+FROM+users
. In questo modo la variabile
$_GET['id']
sarebbe impostata a 1;DELETE FROM users
, che cancellerebbe tutti
i tuoi utenti! Per evitarlo, dovresti sempre pulire l’input ID usando i bound
parameters di PDO.
Questo è codice corretto. Usa un bound parameter in uno statement PDO. In questo modo viene effettuato l’escape dell’input esterno ID prima che questo venga introdotto nel database, evitando potenziali attacchi di tipo SQL injection.
Per le operazioni di scrittura, come INSERT e UPDATE, è particolarmente importante filtrare prima i dati e poi pulirli (rimozione di tag HTML, JavaScript etc.). PDO li pulirà solo rispetto all’SQL, non alla tua applicazione.
Dovresti anche tenere in considerazione che le connessioni al database usano risorse, e non sarebbe strano che tali risorse si esaurissero se le connessioni non vengono chiuse implicitamente (ma è più comune in altri linguaggi). Usando PDO, puoi chiudere implicitamente la connessioni distruggendo l’oggetto, ovvero assicurandoti che tutti i rimanenti riferimenti a esso vengano cancellati (impostati a NULL). Se non lo fai esplicitamente, PHP chiuderà automaticamente la connessione quando il tuo script termina l’esecuzione, a meno che, ovviamente, tu non stia usando delle connessioni persistenti.
Quando gli sviluppatori iniziano a studiare PHP, spesso finiscono per mescolare l’interazione col database con la logica di presentazione, usando codice come questo:
Questo è una pessima pratica per diverse ragioni: principalmente è difficile da debuggare, difficile da testare, difficile da leggere e stamperà molti campi se non imposti un limite.
Nonostante ci siano molte soluzioni per farlo - a seconda che si preferisca l’OOP o la programmazione funzionale - ci dev’essere un elemento di separazione.
Considera il passo più semplice:
Questo è un buon inizio. Metti quei due pezzi in due file diversi e hai una separazione pulita.
Crea una classe per metterci quel metodo e hai un “modello”. Crea un semplice
file .php
per metterci la logica di presentazione e hai una “vista”, che è
molto simile all’MVC - un’architettura OOP comune a molti
framework.
foo.php
models/FooModel.php
views/foo-list.php
Questa è essenzialmente la stessa cosa che fanno molti framework moderni, anche se un po’ più manuale. Potresti non averne sempre bisogno, ma mischiare insieme troppa logica di presentazione e interazione col database può essere un problema serio se vorrai mai fare lo unit testing della tua applicazione.
PHPBridge ha un’ottima risorsa chiamata Creating a Data Class che copre un argomento simile, ed è perfetta per sviluppatori che stanno prendendo famigliarità solo ora col concetto di interazione coi database.
Molti framework forniscono il proprio livello di astrazione, che a volte è basato su PDO. Spesso questi emulano in un sistema di database funzionalità presenti solo in un altro, fornendoti dei metodi PHP per costruire le tue query; in questo modo forniscono un’astrazione reale del database invece della semplice astrazione della connessione fornita da PDO. Ovviamente, questo complica leggermente le cose, ma se stai costruendo un’applicazione portatile che deve funzionare con MySQL, PostgreSQL e SQLite, allora un po’ di complicazione può essere introdotta per avere del codice pulito.
Alcuni livelli di astrazione sono stati costruiti usando gli standard di namespace PSR-0 o PSR-4, in modo che possano essere installati in qualunque applicazione:
I template sono un modo comodo per separare la logica dei controller e quella di dominio dalla logica di presentazione. Tipicamente i template contengono il codice HTML della tua applicazione, ma possono essere usati anche per altri formati, come l’XML. I template vengono spesso chiamati anche “viste”, che costituiscono parte del secondo componente del pattern di architettura del software model–view–controller (MVC).
Il beneficio principale derivante dall’uso dei template è la separazione che creano tra la logica di presentazione e il resto della tua applicazione. I template hanno la sola responsabilità di visualizzare contenuto formattato. Non sono responsabili per il recupero o la persistenza dei dati o altri compiti più complessi. Questo porta alla scrittura di codice più pulito e più facile da leggere, particolarmente utile in un team dove gli sviluppatori lavorano sul codice server-side (controller e modelli) e i designer lavorano sul client-side (markup).
I template, inoltre, migliorano l’organizzazione del codice di presentazione. I template sono generalmente posti in una cartella “views”, ciascuno definito in un singolo file. Questo approccio incoraggia il riutilizzo del codice: grandi blocchi di codice vengono spezzati in pezzi più piccoli e riutilizzabili, spesso chiamati template o viste parziali (“partials”). Per esempio, l’header e il footer del tuo sito possono essere definiti ciascuno in un template e venire poi inclusi prima e dopo ciascun template di pagina.
Infine, a seconda della libreria che usi, i template possono offrire maggiore sicurezza eseguendo l’escape automatico del contenuto generato dall’utente. Alcune librerie offrono anche una funzionalità di sand-boxing: in questo caso i designer dei template hanno accesso solo a variabili e funzioni autorizzate.
I template scritti in PHP sono semplicemente dei template che usano codice PHP nativo. Sono una scelta naturale dato che PHP stesso è un linguaggio per i template. Questo significa semplicemente che puoi includere codice PHP in altro codice, come l’HTML. Si tratta di un beneficio per gli sviluppatori PHP perché non c’è nessuna nuova sintassi da imparare, conoscono le funzioni disponibili, e i loro editor PHP hanno già l’evidenziazione della sintassi e l’autocompletamento integrati. Inoltre, i template PHP sono generalmente molto veloci perché non richiedono compilazione.
Ogni framework PHP moderno utilizza qualche tipo di sistema di template, la maggior parte dei quali usano PHP di default. Al di là dei framework, librerie come Plates o Aura.View semplificano il lavoro con i template PHP offrendo funzionalità di templating moderne come l’ereditarietà, i layout e le estensioni.
Usando la libreria Plates.
Usando la libreria Plates.
Nonostante PHP si sia evoluto fino a diventare un linguaggio maturo e orientato agli oggetti, non è migliorato molto come linguaggio di templating. I template compilati, come Twig o Smarty*, sopperiscono a questa mancanza offrendo una nuova sintassi che è stato studiata appositamente per il templating. Dall’escaping automatico all’ereditarietà, passando per le strutture di controllo semplificate, i template compilati sono disegnati per essere più semplici da scrivere, più puliti da leggere e più sicuri da usare. I template compilati possono anche essere condivisi tra diversi linguaggi, e Mustache ne è un buon esempio. Poiché questi template devono essere compilati c’è un leggero impatto sulla performance, ma è minimo quando si usa un sistema di caching appropriato.
*Nonostante Smarty offra l’escaping automatico, questa funzionalità NON è abilitata di default.
Usando la libreria Twig.
Usando la libreria Twig.
In molti linguaggi di programmazione, ogni volta che qualcosa va storto viene lanciata un’eccezione. Questo è certamente un modo possibile di fare le cose, ma PHP è un linguaggio con poche eccezioni. Nonostante supporti le eccezioni e sempre più del codice nativo stia usando a usarle quando si lavora con gli oggetti, la maggior parte di PHP cercherà di continuare a processare indipendentemente da quello che accade, a meno che non avvenga un errore fatale.
Per esempio:
Questo è solo un errore notice, e PHP continuerà felicemente. Questo può confondere chi viene da linguaggi con molte eccezioni, perché riferirsi a una variabile mancante in Python, per esempio, lancia un’eccezione:
L’unica vera differenza è che Python andrà nel panico per ogni piccola cosa, in modo che gli sviluppatori possano essere completamente sicuri che qualunque potenziale problema o caso limite sia coperto, mentre PHP continuerà a processare a meno che non avvenga qualcosa di estremo; a questo punto lancerà un errore e lo riporterà.
PHP ha diversi livelli di gravità degli errori. I tre tipi più comuni di
messaggi sono gli errori, i notice e i warning. Questi hanno diversi livelli di
gravità: E_ERROR
, E_NOTICE
e E_WARNING
. Gli errori sono errori fatali che
avvengono durante l’esecuzione; sono solitamente causati da problemi nel tuo
codice e devono essere sistemati perché impediranno l’esecuzione di PHP. I
notice sono messaggi di avviso causati da codice che potrebbe o meno causare
problemi durante l’esecuzione dello script; l’esecuzione non viene fermata. I
warning sono errori non fatali: l’esecuzione dello script non viene fermata.
Un altro tipo di messaggio di errore riportato durante la compilazione sono i
messaggi E_STRICT
. Questi messaggi sono usati per suggerire cambiamenti al tuo
codice per assicurare la migliore interoperabilità e compatibilità con le
versioni successive di PHP.
Il segnalazione degli errori può essere cambiato usando le impostazioni di PHP
e/o delle chiamate a funzioni PHP. Usando la funzione nativa di PHP
error_reporting()
puoi impostare il livello degli errori per la durata
dell’esecuzione dello script passando una delle costanti di livello errore
predefinite. Questo significa che se vuoi vedere solo warning ed errori - ma non
notice - allora puoi configurarlo così:
Puoi anche controllare se gli errori vengono visualizzati a schermo (ottimo per lo sviluppo) o se vengono nascosti e loggati (ottimo per la produzione). Per maggiori informazioni controlla la sezione Segnalazione degli errori.
Puoi anche dire a PHP di sopprimere errori specifici usando l’operatore di
controllo degli errori @
. Metti questo operatore all’inizio di un’espressione,
e ogni errore che è un risultato diretto dell’espressione viene silenziato:
Questo mostrerà $foo['bar']
se esiste, ma restituirà semplicemente un valore
nullo e non visualizzerà niente se la variabile $foo
o l’indice 'bar'
non
esistono. Senza l’operatore di controllo degli errori, questa espressione
potrebbe creare un errore PHP Notice: Undefined variable: foo
o PHP Notice:
Undefined index: bar
.
Questa potrebbe sembrare una buona idea, ma ci sono alcuni lati negativi. PHP
gestisce le espressioni che usano un @
in maniera meno performante rispetto a
quelle senza @
. L’ottimizzazione prematura potrebbe essere la radice di tutti
i dibattiti sulla programmazione, ma se la performance è particolarmente
importante per la tua applicazione/libreria, è importante capire le conseguenze
che l’operatore di controllo degli errori avrà sulla performance.
In secondo luogo, l’operatore di controllo degli errori inghiotte completamente l’errore. L’errore non viene mostrato, e l’errore non viene mandato al log degli errori. Inoltre, i sistemi PHP di produzione non hanno modo di disabilitare l’operatore di controllo degli errori. Nonostante l’errore che vedi potrebbe essere innocuo, un errore differente e meno innocuo verrebbe ugualmente silenziato.
Se c’è un modo di evitare l’operatore di soppressione degli errori, dovresti consdierarlo. Per esempio, il nostro codice sopra potrebbe essere riscritto così:
Un caso in cui la soppressione degli errori potrebbe avere senso è quando
fopen()
non trova il file da caricare. Potresti controllare l’esistenza del
file prima di provare a caricarlo, ma se il file viene cancellato dopo il
controllo e prima di fopen()
(il che potrebbe sembrare impossibile, ma può
accadere) allora fopen()
restituirà false e lancerà un errore. Questo è
potenzialmente qualcosa che PHP dovrebbe risolvere, ma è un caso in cui la
soppressione degli errori potrebbe sembrare l’unica soluzione valida.
Prima abbiamo detto che non c’è modo in un sistema PHP tradizionale di
disabilitare l’operatore di controllo degli errori. Tuttavia, Xdebug ha
un’impostazione ini xdebug.scream
che disabilita l’operatore di controllo
degli errori. Puoi impostarlo nel tuo php.ini
scrivendo:
xdebug.scream = On
Puoi anche impostare questo valore durante l’esecuzione con la funzione ini_set
:
L’estensione PHP “Scream” offre una funzionalità simile a quella di Xdebug, ma
l’impostazione ini di Scream si chiama scream.enabled
.
Questo è particolarmente utile quando stai debuggando del codice e sospetti che un messaggio di errore informativo venga soppresso. Usa scream con cura, come uno strumento di debugging temporaneo. Ci sono molte librerie PHP che potrebbero non funzionare con l’operatore di controllo degli errori disabilitato.
PHP è perfettamente in grado di essere un linguaggio fortemente orientato alle
eccezioni, e richiede solo qualche linea di codice per fare il cambio.
Fondamentalmente puoi lanciare i tuoi “errori” come “eccezioni” usando la classe
ErrorException
, che estende la classe Exception
.
Questa è una pratica comune implementata da un grande numero di framework
moderni come Symfony e Laravel. Di default Laravel visualizzerà tutti gli errori
e le eccezioni usando il pacchetto Whoops! se l’interruttore app.debug
è
acceso, oppure li nasconderà se l’interruttore è spento.
Lanciando gli errori come eccezioni durante lo sviluppo puoi gestirli meglio del solito, e se vedi un’eccezione durante lo sviluppo puoi racchiuderla in un’istruzione di cattura con codice specifico per gestire la situazione. Ciascuna eccezione che catturi rende istantaneamente la tua applicazione un po’ più robusta.
Maggiori informazioni su questo e su come usare la classe ErrorException
per
gestire gli errori si possono trovare su classe ErrorException.
Le eccezioni sono una parte standard della maggior parti dei linguaggi di programmazione famosi, ma sono spesso ignorate dai programmatori PHP. Linguaggi come Ruby fanno un uso massiccio delle eccezioni, quindi ogni volta che qualcosa va storto come una richiesta HTTP che fallisce, o una query al database che non funziona, o anche se un’immagine non può essere trovata, Ruby (o le gem usate) lancerà un’eccezione a schermo in modo che tu sappia subito che c’è un errore.
PHP stesso è piuttosto negligente in questo senso: una chiamata a
file_get_contents()
su un file inesistente non farà che restituire FALSE
e
un warning. Molti vecchi framework PHP come CodeIgniter si limiteranno a
restituire false, loggare un messaggio nei loro log proprietari e a volte usare
un metodo come $this->upload->get_error()
per vedere cos’è andato storto. Il
problema qui è che devi cercare l’errore e controllare la documentazione per
vedere come recuperare l’errore di quella classe, invece di averlo subito ovvio.
Un altro problema è quando le classi lanciano un errore a schermo automaticamente e terminano il processo. Facendo questo, impedisci a un altro sviluppatore di gestire dinamicamente l’errore. Le eccezioni dovrebbero essere lanciate per mettere a conoscenza lo sviluppatore di un errore; starà a loro scegliere come gestirlo. Esempio:
La classe generica Exception
fornisce molte poche informazioni di debug per lo
sviluppatore; tuttavia, per rimediare a questo, è possibile creare una versione
specializzata di Exception
estendola:
Questo significa che puoi aggiungere più blocchi catch e gestire differenti eccezioni in modo differente. Questo può portare alla creazione di molte eccezioni personalizzate, alcune delle quali avrebbero potuto essere evitate usando le eccezioni SPL fornite dall’estensione SPL.
Se per esempio usi il metodo magico __call()
e un metodo non valido è
richiesto, invece di lanciare un’eccezione standard, troppo vaga, o creare
un’eccezione personalizzata solo per quello, potresti solo eseguire throw new
BadFunctionCallException()
.
Ci sono cattive persone pronte e desiderose di manipolare la tua applicazione Web. È importante che prendi le precauzioni necessarie per irrigidire la sicurezza della tua applicazione Web. Fortunatamente, i ragazzi dell’Open Web Application Security Project hanno compilato una lunga lista di vulnerabilità di sicurezza note e metodi per proteggerti contro di esse. Questa guida dev’essere necessariamente letta da qualunque sviluppatore che abbia a cura la sicurezza.
Prima o poi chiunque crea un’applicazione PHP che richiede il login degli utenti. Username e password vengono salvati nel database e usati successivamente per autenticare gli utenti al login.
È importante effettuare un hashing appropriato delle password prima di salvarle. L’hashing delle password è una funzione irreversibile che viene eseguita sulle password degli utenti. Essa produce una stringa a lunghezza fissa che non può essere decriptata. Ciò significa che puoi confrontare l’hash con un altro per determinare se provengono tutti dalla stessa stringa d’origine, ma non puoi determinare la stringa di origine. Se l’hashing delle password non viene effettuato e il tuo database è letto da una persona non autorizzata, tutti gli account utente sono compromessi. Alcuni utenti potrebbero (sfortunatamente) usare la stessa password per altri servizi. Dunque, è importante gestire la sicurezza seriamente.
In PHP 5.5 è stata introdotta la funzione password_hash
. In questo momento
utilizza l’algoritmo BCrypt, che è il più potente attualmente supportato da PHP.
Sarà aggiornata in futuro per supportare altri algoritmi. La libreria
password_compat
è stata creata per fornire compatibilità per PHP >= 5.3.7.
Nell’esempio sotto calcoliamo l’hash di una stringa, quindi confrontiamo l’hash con una nuova stringa. Poiché le nostre stringhe di origine sono differenti (‘secret-password’ e ‘bad-password’) questo login fallirà.
Non fidarti mai (mai!) dell’input esterno introdotto nel tuo codice PHP.
Sanitizza e valida sempre l’input prima di usarlo nel tuo codice. Le funzioni
filter_var
e filter_input
possono sanitizzare il testo e validare certi
formati (es. indirizzi email).
L’input esterno può essere qualunque cosa: dati di form da $_GET
e $_POST
,
alcuni valori nella variabile superglobale $_SERVER
, e il corpo della
richiesta HTTP recuperato tramite fopen('php://input', 'r')
. Ricorda, l’input
esterno non è limitato ai form inviati dall’utente. Anche i file caricati e
scaricati, i valori di sessione, i dati nei cookie e i dati da servizi Web di
terze parti sono input esterno.
Anche se l’input esterno può essere salvato, combinato e letto successivamente, è ancora input esterno. Ogni volta che processi, visualizzi, concateni o includi dati nel tuo codice, chiediti se sono stati filtrati appropriatamente e se ci si può fidare di essi.
I dati possono essere filtrati diversamente a seconda del loro scopo. Per
esempio, quando input esterno non filtrato è passato nell’output HTML della
pagina, può esguire codice HTML e JavaScript sul tuo sito! Questo è conosciuto
come Cross-Site Scripting (XSS) e può essere un attacco molto pericoloso. Un
modo per evitare l’XSS è sanitizzare tutti i dati generati dall’utente prima di
visualizzarlo nella tua pagina, rimuovendo i tag HTML con la funzione
strip_tags
o eseguendo l’escape di caratteri dal significato speciale nelle
loro rispettive entità HTML con le funzioni htmlentities
o htmlspecialchars
.
Un altro esempio è il passaggio di opzioni alla linea di comando. Questo può
essere molto pericoloso (ed è solitamente una cattiva idea), ma puoi usare la
funzione nativa escapeshellarg
per sanitizzare gli argomenti del comando
eseguito.
Un ultimo esempio è l’accettazione di input esterno per determinare un file da caricare dal filesystem. Questa vulnerabilità può essere sfruttata cambiando il nome di file in un path di file. Devi rimuovere “/”, “../”, i byte nulli o altri caratteri dal path in modo che non possa caricare file nascosti, non pubblici o con informazioni sensibili.
filter_var
filter_input
La sanitizzazione rimuove (o fa l’escape) i caratteri non permessi o pericolosi dall’input esterno.
Per esempio, dovresti sanitizzare l’input esterno prima di includerlo in codice HTML o inserirlo in una query SQL grezza. Quando usi i parametri di PDO, esso sanitizzerà l’input per te.
A volte è richiesto di consnetire alcuni tag HTML sicuri nell’input quando viene incluso nella pagina HTML. Questo è molto difficile da fare e molti lo evitano usando una formattazione più ristretta come Markdown o BBCode, tuttavia esistono alcune librerie come HTML Purifier per svolgere questo compito.
Vedi i filtri di sanitizzazione
La validazione serve per assicurarsi che l’input esterno contenga ciò che ti aspetti. Per esempio, potresti voler validare un indirizzo email, un numero di telefono o un’età quando processi una richiesta di registrazione.
Nella creazione di file di configurazione per la tua applicazione, le migliori pratiche raccomandano l’utilizzo di uno dei seguenti metodi:
È consigliato salvare le informazioni di configurazioni dove non possono essere lette direttamente tramite il file system
Se devi salvare i tuoi file di configurazione nella root pubblica, chiama i
file con estensione .php
. Questo assicura che, anche se uno script è
eseguito direttamente, non sarà visualizzato come testo semplice.
Le informazioni nei file di configurazione dovrebbero essere protette appropriatamente, tramite crittografia o permessi del filesystem per gruppo/utente
NOTA: A partire da PHP 5.4.0 l’opzione register_globals
è stata rimossa e
non può più essere usata. Questo è incluso solo come avvertimento per chiunque
stia aggiornando una vecchia applicazione.
Quando abilitata, l’opzione register_globals
farà sì che molti tipi di
variabili (incluse quelle da $_POST
, $_GET
e $_REQUEST
) siano disponibili
nello scope globale dell’applicazione. Questo può facilmente portare a problemi
di sicurezza, perché la tua applicazione non può stabilire con certezza da dove
arrivano i dati.
Per esempio: $_GET['foo']
sarebbe disponibile tramite $foo
, che può
sovrascrivere le variabili non dichiarate. Se stai usando PHP < 5.4.0,
assicurati che register_globals
sia off.
Il logging degli errori può essere utile per trovare i punti problematici della tua applicazione, ma può anche esporre informazioni riguardo la sua struttura al mondo esterno. Per proteggere efficacemente la tua applicazione da problemi che potrebbero essere causati dalla visualizzazioni di questi messaggi, devi configurare il tuo server diversamente negli ambienti di sviluppo e produzione.
Per mostrare ogni possibile errore durate lo sviluppo,
configura le seguenti opzioni nel tuo php.ini
:
Il valore
-1
visualizzerà ogni possibile errore, anche quando nuovi livelli verranno aggiunti in versioni future di PHP. Anche la costanteE_ALL
si comporta in questo modo a partire da PHP 5.4. - php.net
Il livello di errore E_STRICT
è stato introdotto nella versione 5.3.0 e non è
parte di E_ALL
, tuttavia lo è diventato nella 5.4.0. Questo significa che se
vuoi segnalare ogni possibile errore nella 5.3 devi usare -1
o
E_ALL | E_STRICT
.
Segnalare ogni possibile errore nelle diverse versioni di PHP
-1
o E_ALL
-1
o E_ALL | E_STRICT
-1
o E_ALL
Per nascondere gli errori in produzione configura così il tuo
php.ini
:
Con queste impostazioni in produzione, gli errori saranno comunque loggati nei log del web server, ma non saranno visualizzati all’utente. Per maggiori informazioni su queste impostazioni, vedi il manuale di PHP:
Scrivere test automatizzati per il tuo codice PHP è considerata una buona pratica e può portare a un’applicazione ben costruita. I test automatizzati sono un ottimo strumento per assicurarsi che la tua applicazione non si rompa quando cambi qualcosa o aggiungi una nuova funzionalità e non dovrebbero essere ignorati.
Ci sono diversi tipi di strumenti (o framework) per il testing in PHP, ciascuno con un approccio differente; tutti quanti cercano di evitare la necessità di testare manualmente e di assemblare grandi team per il Controllo Qualità solo per assicurarsi che i recenti cambiamenti non rompano funzionalità esistenti.
Da Wikipedia:
Il Test Driven Development, in sigla TDD (in italiano: Sviluppo guidato dalle verifiche) è un processo di sviluppo del software in cui lo sviluppo vero e proprio è preceduto (e guidato, driven) dalla stesura di test automatici. Il processo si articola sulla ripetizione di brevi cicli di sviluppo e collaudo (noti come “cicli TDD”, TDD cycles) suddivisi in tre fasi successive, sintetizzate dal motto “Red-Green-Refactor”.
Ci sono molti modi diversi di testare la tua applicazione.
Lo unit testing è un approccio di programmazione usato per assicurarsi che funzioni, classi e metodi funzionino come ci si aspetta durante l’intero ciclo di sviluppo. Controllando i valori di input e output delle funzioni e dei metodi, puoi accertarti che la logica interna funzioni correttamente. Usando l’iniezione delle dipendenze e creando classi mock e stub puoi verificare che le dipendenze vengano usate correttamente per una copertura dei test ancora migliore.
Quando crei una classe o funzione dovresti creare uno unit test per ogni comportamento che deve assumere. Come minimo dovresti assicurarti che generi un errore se le invii argomenti non validi e che funzioni se le invii argomenti validi. Questo aiuterà ad assicurarsi che, quando cambi qualcosa in questa classe o funzione successivamente nel ciclo di sviluppo, la vecchia caratteristica continuerà a funzionare come previsto. L’unica alternativa a questo sarebbe var_dump() in un file test.php, il che non è un modo corretto per creare un’applicazione, sia piccola che grande.
L’altro utilizzo per gli unit test è nel contributo a progetti open source. Se riesci a scrivere un test che mostra una caratteristica non funzionante, lo sistemi e mostri che ora il test passa, le patch saranno accettate molto più facilmente. Se hai intenzione di lanciare un progetto che accetta contributi esterni, questo dovrebbe essere un requisito.
PHPUnit è lo standard de-facto per la scrittura di unit test per applicazioni PHP, ma ci sono diverse alternative:
Da Wikipedia:
L’integration testing (a volte chiamato Integration and Testing, abbreviato “I&T”) è la fase del testing software in cui i moduli individuali vengono combinati e testati come un insieme. Si piazza dopo lo unit testing e prima del validation testing. L’integration testing prende come input moduli su cui è già stato effettuato unit testing, li raggruppa in aggregati più grandi, applica i test definiti nel piano di integration testing a questi aggregati e invia come output il sistema integrato, pronto per l’esecuzione del system testing.
Molti degli strumenti per lo unit testing possono essere usati anche per l’integration testing, giacché molti dei principi di base sono gli stessi.
A volte conosciuto anche come acceptance testing, il functional testing consiste nell’utilizzo di strumenti per la creazione di test automatizzati che usino realmente la tua applicazione invece di limitarsi a verificare che unità individuali di codice si comportino correttamente e riescano a parlare l’una con l’altra. Questi strumenti funzionano generalmente utilizzando dati reali e simulati utenti dell’applicazione esistenti.
Ci sono due differenti tipi di Behavior-Driven Development (BDD): SpecBDD e StoryBDD. Lo SpecBDD si concentra sul comportamento tecnico del codice, mentre lo StoryBDD si concentra sulle interazioni. PHP ha dei framework per entrambi i tipi di BDD.
Con lo StoryBDD, scrivi delle storie leggibili da esseri umani che descrivono il comportamento della tua applicazione. Queste storia possono poi essere eseguite come veri e propri test per la tua applicazione. Il framework usato nelle applicazioni PHP per lo StoryBDD è Behat, che si ispira al progetto Ruby Cucumber e implementa il DSL Gherkin per la descrizione delle funzionalità.
Con lo SpecBDD, scrivi delle specifiche che descrivono come il tuo codice dovrebbe funzionare. Invece di testare una funzione o un metodo, descrivi come quella funzione o metodo dovrebbero comportarsi. PHP offre il framework PHPSpec per questo scopo. Questo framework si ispira al progetto Ruby RSpec.
Oltre ai framework di testing individuali, ci sono anche altri framework generici e librerie di aiuto utili per ogni approccio.
Le applicazioni PHP possono essere pubblicate ed eseguite sui Web server di produzione in diversi modi.
PaaS fornisce il sistema e l’architettura di rete necessari per eseguire applicazioni PHP in Rete. Questo significa che c’è bisogno di poca o nessuna configurazione per lanciare applicazioni e framework PHP.
Recentemente PaaS è diventato un metodo piuttosto usato per la pubblicazione, l’hosting e la scalatura di applicazioni PHP di ogni dimensione. Puoi trovare una lista di provider PHP PaaS “Platform as a Service” nella nostra sezione risorse.
Se hai dimestichezza con l’amministrazione di un sistema o vuoi impararla, i server virtuali o dedicati ti danno totale controllo sull’ambiente di produzione della tua applicazione.
PHP, tramite il FastCGI Process Manager (FPM) integrato, si integra molto bene con nginx, che è un server leggero dalle alte prestazioni. Usa meno memoria di Apache e gestisce meglio le richieste simultanee. Questo è particolarmente importante su server virtuali che non hanno molta memoria.
PHP e Apache hanno fatto molta storia insieme. Apache è totalmente configurabile e ha molti moduli che estendono le sue funzionalità. È una scelta comune per i server condivisi e una configurazione facile per i framework PHP e le applicazioni open source come WordPress. Sfortunatamente, Apache usa più risorse di nginx di default e non riesce a gestire così tanti visitatori contemporeanei.
Ci sono molte configurazioni diverse per eseguire Apache con PHP. La più comune e la più semplice da configurare è il prefork MPM con mod_php5. Nonostante questa non sia la più efficiente in termini di consumo di memoria, è la più semplice da configurare e usare. Questa è probabilmente la scelta migliore se non vuoi addentrarti troppo in profondità nell’amministrazione dei server. Nota che per usare mod_php5 DEVI usare il prefork MPM.
In alternativa, se vuoi ottenere migliori performance e stabilità con Apache puoi usare lo stesso sistema FPM di nginx ed eseguire l’[MPM worker] o l’[MPM event] con mod_fastcgi o mod_fcgid. Questa configurazione sarà molto più efficiente nell’utilizzo di memoria e molto più veloce, ma è più complicata da installare.
Se ti trovi a dover modificare lo schema del database o eseguire i test prima dell’aggiornamento dei file manualmente, ripensaci! Con ogni compito manuale in più che devi eseguire per pubblicare una nuova versione della tua applicazione aumentano le possibilità di un errore fatale. Che tu stia gestendo un semplice aggiornamento, un processo di build completo o una strategia di integrazione continua, l’automazione dello sviluppo è tua amica.
Tra i compiti che potresti voler automatizzare ci sono:
Questi strumenti possono essere descritti come un insieme di script che gestiscono compiti comuni nella pubblicazione del software. Lo strumento non è parte del tuo software, ma agisce su di esso da ‘fuori’.
Ci sono molti strumenti open source disponibili per aiutarti con l’automazione dello sviluppo, alcuni scritti in PHP, altri no. Questo non dovrebbe impedirti di usarli, se sono più adatti per uno specifico compito. Ecco alcuni esempi.
Phing è il modo più facile per iniziare con la pubblicazione automatica nel mondo di PHP. Con Phing puoi controllare la pacchettizazione, la pubblicazione o il processo di testing tramite un semplice file XML. Phing (che è basato su Apache Ant) fornisce un ricco set di compiti solitamente richiesti per installare o aggiornare un’applicazione Web e può essere esteso con compiti personalizzati, scritti in PHP.
Capistrano è un sistema per programmatori medio-avanzati per eseguire comandi in modo strutturato e ripetibile su una o più macchine remote. È pre- configurato per la pubblicazione di applicazioni Ruby on Rails, ma molti lo usano per pubblicare applicazioni PHP. Il suo corretto utilizzo dipende dalla conoscenza di Ruby e Rake.
Il post PHP Deployment with Capistrano sul blog di Dave Gardner è un buon punto d’inizio per programmatori PHP interessati a Capistrano.
Chef è più di un framework di pubblicazione. È un framework di integrazione di sistema molto potente scritto in Ruby che non solo pubblica la tua applicazione ma può costruire l’intero ambiente server o macchina virtuale.
Deployer è uno strumento di pubblicazione scritto in PHP; è semplice e [funzionale. Esegue i compiti in parallelo, supporta la pubblicazione atomica, [mantiene la consistenza tra i server. Ha ricette per compiti comuni relativi a [Symfony, Laravel, Zend Framework e Yii.
L’integrazione continua è una pratica di sviluppo software in cui i membri di un team integrano il loro lavoro frequentemente. Generalmente ogni persona integra il lavoro almeno giornalmente, portando a più integrazioni giornaliere. Molti team trovano che questo approccio riduca notevolmente i problemi di integrazione e permette a un team di sviluppare software coeso più rapidamente.
– Martin Fowler
Ci sono diversi modi di implementare l’integrazione continua in PHP. Recentemente Travis CI ha fatto un buon lavoro nel rendere l’integrazione continua una realtà anche per piccoli progetti. Travis CI è un sistema hostato di integrazione continua per la community open source. È integrato con GitHub e offre supporto di prima classe per molti linguaggi, incluso PHP.
Eseguire la tua applicazione in un ambiente di produzione diverso da quello di sviluppo può portare alla comparsa di strani errori quando pubblichi la tua applicazione. È anche difficile mantenere i diversi ambienti di sviluppo aggiornati all’ultima versione delle librerie usate quando lavori con un team di sviluppatori.
Se stai sviluppando su Windows e pubblicando su Linux (o qualunque cosa che non sia Windows) o stai sviluppando in un team, dovresti considerare la possibilità di usare una macchina virtuale. Può sembrare complicato, ma oltre agli ambienti di virtualizzazione più conosciuti come VMware e VirtualBox, ci sono strumenti addizionali che potrebbero aiutarti a configurare un ambiente virtuale in pochi semplici passi.
Vagrant ti aiuta a costruire le tue macchine virtuali sfruttando ambienti virtuali noti, e configura questi ambienti basandosi su un singolo file di configurazione. Queste macchine possono essere configurate manualmente, oppure puoi usare un software di “provisioning” come Puppet o Chef per farlo al posto tuo. Eseguire il provisioning della macchina di base è un ottimo modo per assicurarti che più macchine vengano configurate nella stessa maniera e rimuove la necessità di mantenere complicate liste di comandi d’installazione. Puoi anche “distruggere” la macchina e ricrearla senza troppi passi manuali, rendendo così semplice creare un’installazione “fresca”.
Vagrant crea delle cartelle per condividere il codice tra l’host e la tua macchina virtuale, il che significa che puoi creare e modificare file sul tuo host e poi eseguire il codice nella macchina virtuale.
Se ti serve un picolo aiuto per iniziare a usare Vagrant ci sono dei servizi che potrebbero essere utili:
tipiche (PHP tra le varie opzioni). Il provisioning è effettuato con Chef.
PHP. Fortemente concentrato su PHP. Oltre alle macchine virtuali locali, può anche essere usato per configurare servizi cloud. Il provisioning è effettuato con Puppet.
macchine virtuali per lo sviluppo web. Un singolo documento YAML controlla tutto ciò che viene installato sulla macchina virtuale.
Playbook Ansible per progetti basati su PHP.
Oltre a usare Vagrant, un altro semplice modo per configurare un ambiente di sviluppo e uno di produzione è Docker. Docker ti aiuta a fornire container Linux per ogni tipo di applicazione. Ci sono molte immagini Docker utili che possono fornirti altri ottimi servizi (es. MySQL, PostgreSQL e molti altri) senza la necessità di installare tali servizi sulla tua macchina locale. Dai un’occhiata al Docker Hub Registry per avere una lista dei contenitori pre-fabbricati disponibili, che potrai poi eseguire ed usare con facilità.
Dopo aver installato docker sulla tua macchina, potrai avviare
un’istanza di Apache con supporto a PHP in un solo passo. Il comando seguente
scaricherà un’installazione di Apache completamente funzionante con l’ultima
versione di PHP, e renderà disponibile la directory /path/ai/tuoi/file/php
all’indirizzo http://localhost:8080
:
Dopo aver eseguito docker run
il tuo container sarà inizializzato ed eseguito.
Se vuoi fermare o avviare nuovamente il tuo container, puoi usare il nome che
hai fornito ed eseguire semplicemente docker stop mio-webserver-php
e
docker start mio-webserver-php
senza fornire nuovamente i parametri menzionati
sopra.
I comandi menzionati sopra mostrano solo un modo veloce per eseguire un web server Apache con supporto a PHP, ma ci sono molte altre cose che puoi fare con Docker. Una delle cose più importanti per gli sviluppatori PHP è collegare il proprio web server con l’istanza di un database, per esempio. La Docker User Guide spiega nel dettaglio come farlo.
PHP è piuttosto veloce già di suo, ma possono sorgere dei problemi quando esegui connessioni remote, carichi file etc. Per fortuna, ci sono diversi strumenti a disposizione per velocizzare certe parti dell’applicazione, o ridurre il numero di volte che questi compiti lenti devono essere eseguiti.
Quando un nuovo PHP file viene eseguito, è prima compilato in opcode; solo dopo l’opcode viene eseguito. Se un file PHP non viene modificato, l’opcode rimane lo stesso. Questo significa che il processo di compilazione è uno spreco di risorse computazionali.
È qui che le cache dell’opcode entrano in gioco. Evitano compilazioni inutili salvando l’opcode in memoria e riusandolo nelle chiamate successive. Impostare una cache dell’opcode è una questione di minuti, e la tua applicazione sarà molto più veloce. Non c’è alcuna ragione per non usarla.
A partire da PHP 5.5, c’è una cache dell’opcode integrata chiamata OPcache. È anche disponibile per versioni precedenti.
Altre risorse sulle cache dell’opcode:
Alcune volte può essere utile mettere in cache oggetti singoli nel tuo codice, come, per esempio, dati che sono lenti da ottenere o chiamate al database il cui risultato cambia difficilmente. Puoi usare software di caching degli oggetti per mantenere questi pezzi di dati in memoria per un successivo accesso estremamente veloce. Se salvi questi elementi in un data store dopo averli recuperati, e poi li prendi direttamente dalla cache per le richieste successive, puoi ottenere un notevole miglioramento delle performance e riducendo il carico del tuo database.
Molte soluzioni famose di caching del bytecode ti permettono anche di mettere in cache dati personalizzati, dunque ci sono ancora più ragioni per trarne vantaggio. APCu, XCache e WinCache forniscono tutti API per salvare dati dal tuo codice PHP nella loro memoria cache.
I sistemi di caching degli oggetti più comunemente usati sono APCu e memcached. APCu è una scelta eccellente per il caching degli oggetti. Include una semplice API per aggiungere i tuoi dati alla sua memoria cache ed è molto semplice da configurare e usare. L’unica vera limitazione di APCu è che è legato al Web server su cui è installato. Memcached, invece, è installato come un servizio separato e può essere letto dalla rete, il che significa che puoi memorizzare oggetti in un data store super-veloce in una posizione centrale e molti sistemi diversi possono accedervi.
Nota che quando esegui PHP come un’applicazione (Fast-)CGI nel tuo Web server, ogni processo PHP avrà la sua cache (i dati di APCu non sono condivisi tra i processi). In questi casi, potresti voler usare memcached, che non è legato ai processi PHP.
In una configurazione di rete APCu sarà generalmente più performante di memcached in termini di velocità di accesso, ma memcached potrà scalare meglio e più velocemente. Se non pensi di eseguire la tua applicazioni su server multipli, o non ti servono le funzionalità aggiuntive che memcached offre, allora APCu è probabilmente la scelta migliore per il caching degli oggetti.
Esempio di utilizzo con APCu:
Prima di PHP 5.5, APC fornisce sia una cache degli oggetti che una cache del bytecode. APCu è un progetto per portare la cache degli oggetti di APC a PHP 5.5 e successivi, dato che PHP Ora ha una cache del bytecode integrata (OPCache).
PHPDoc è uno standard informale per i commenti al codice PHP. Ci sono molti tag diversi disponibili. La lista completa dei tag e degli esempi può essere trovata nel manuale di PHPDoc.
Qui sotto c’è un esempio di come potresti documentare una classe con alcuni metodi:
La documentazione della classe ha un tag @author e un tag @link. Il tag @author è usato per documentare l’autore del codice e può essere ripetuto per documentare più autori. Il tag @link è usato per linkare a un sito web che ha una relazione col codice.
Dentro la classe, il primo metodo ha un tag @param che documenta il tipo, il nome e la descrizione del parametro passato al metodo. Inoltre, ha dei tag @return e @throws che documentano rispettivamente il tipo restituito e qualunque eccezione che potrebbe essere lanciata.
Il secondo e il terzo metodo sono molto simili e hanno un solo tag @param come
il primo metodo. La differenza importante nel secondo e terzo metodo è
l’inclusione/esclusione del tag @return. @return void
informa esplicitamente
che non sarà restituito nulla; storicamente, omettere la dichiarazione @return
void
ha lo stesso significato (nessuna restituzione).
Piuttosto che reinventare la ruota, molti provider PHP usano dei framework per costruire le proprie applicazioni. I framework astraggono la maggior parte dei dettagli di basso livello e forniscono delle utili interfacce di semplice utilizzo per realizzare molte funzionalità comuni.
Non hai bisogno di un framework per ogni progetto. A volte il solo PHP è il modo giusto per realizzare le cose, ma se hai bisogno di un framework, ce ne sono tre tipi:
I micro-framework forniscono essenzialmente un modo per mappare una richiesta HTTP a un callback, un controller o un metodo il più velocemente possibile, e a volte forniscono alcune libreria extra per aiutare nello sviluppo come librerie di base per il database e cose del genere. Sono prevalentemente usati nella costruzione di servizi HTTP remoti.
Molti framework aggiungono un nome considerevole di funzionalità a quelle disponibili in un micro-framework; questi vengono detti framework completi. Di solito sono distribuiti con degli ORM, pacchetti per l’autenticazione etc.
I framework a componenti sono insiemi di librerie specializzate e con una sola responsabilità. Diversi framework a componenti possono essere usati insieme per creare un micro-framework o un framework completo.
Come menzionato sopra, i componenti sono un altro approccio alla creazione, distribuzione e implementazione di codice condiviso. Esistono diversi repository di componenti; i due più famosi sono:
Entrambi questo repository hanno degli strumenti da linea di comando associati per aiutarti nel processo di installazione e aggiornamento, e sono stati spiegati in dettaglio nella sezione Gestione delle dipendenze.
Ci sono anche dei framework a componenti e provider componenti che non offrono alcun framework. Questi progetti forniscono solo un’altra sorgente di pacchetti che idealmente hanno poche o nessuna dipendenza verso altri pacchetti o framework specifici.
Per esempio, puoi usare il pacchetto Validation di FuelPHP senza dover usare il framework FuelPHP.
I componenti Illuminate di FuelPHP saranno meglio separati dal framework Laravel. Per ora, solo i componenti meglio separati sono elencati sopra.
Ci sono un sacco di libri in giro su PHP, ma alcuni sono molto vecchi e non contengono più informazioni accurate. Ci sono anche libri pubblicati per “PHP 6” che non esiste, e non esisterà mai. La prossima versione di PHP sarà chiamata “PHP 7” per via di questi libri.
Questa sezione mira a essere un documento in costante aggiornamento sui libri raccomandati per lo sviluppo PHP in generale. Se vuoi che il tuo libro sia aggiunto, invia una PR e sarà presa in esame.
La comunità PHP è tanto diversificata quanto grande, e i suoi membri sono pronti e desiderosi di aiutare i nuovi programmatori PHP. Considera l’idea di entrare nel tuo gruppo PHP locale (PUG) o di partecipare a conferenze PHP più grandi per avere maggiori informazioni sulle pratiche qui descritte. Puoi passare nel canale IRC #phpc su irc.freenode.com e seguire l’account Twitter @phpc. Fatti vedere, incontra nuovi sviluppatori, impara nuove cose e, soprattutto, fai nuovi amici! Altre risorse della comunità includono la Comunità programmatori PHP su Google+ e StackOverflow.
If you live in a larger city, odds are there’s a PHP user group nearby. You can easily find your local PUG at
the usergroup-list at php.net which is based upon PHP.ug. Alternate sources might be
Meetup.com or a search for php user group near me
using your favourite search engine
(i.e. Google). If you live in a smaller town, there may not be a local PUG; if that’s the case, start one!
Special mention should be made of two global user groups: NomadPHP and PHPWomen. NomadPHP offers twice monthly online user group meetings with presentations by some of the top speakers in the PHP community. PHPWomen is a non-exclusive user group originally targeted towards the women in the PHP world. Membership is open to everyone who supports a more diverse community. PHPWomen provide a network for support, mentorship and education, and generally promote the creating of a “female friendly” and professional atmosphere.
La comunità PHP tiene anche delle conferenze regionali e nazionali in molti Paesi in tutto il mondo. A questi eventi parlano generalmente membri noti della comunità PHP, dunque è una buona opportunità per imparare direttamente dai leader del settore.