Cos'è PHP?





PHP nasce nel 1994, ad opera di Rasmus Lerdorf


E un progetto di tipo open source


Alla fine del 1998 erano circa 250.000 i server Web che supportavano PHP: per superare i 10 milioni alla fine del 2002, quando è stata rilasciata la versione 4.3.0.

Oggi PHP è conosciuto come PHP: Hypertext Preprocessor, ed è un linguaggio completo di scripting, sofisticato e flessibile, che può girare praticamente su qualsiasi server Web, su qualsiasi sistema operativo, e consente di interagire praticamente con qualsiasi tipo di database (MySql, PostgreSql, Sql Server, Oracle, SyBase, Access e altri).



Funzionamento del PHP: lato server, lato client



Lato server: l'interprete esegue il codice (php o altro), che produce altro codice html: ad esempio, PHP potrebbe controllare che ore sono e generare un messaggio di questo tipo: "Buon pomeriggio, sono le 17.10!" Dopo l'esecuzione, la pagina non conterrà più codice php, ma solo html. A questo punto è pronta per essere spedita al browser. Quindi l'utente vede solo il codice html, e non ha accesso al codice che ha generato la pagina.

Lato client: JavaScript ad esempio viene eseguito non dal server, ma dal browser dell'utente (il client, appunto). JavaScript ci consente di eseguire operazioni che riguardano il sistema dell'utente, come ad esempio aprire una nuova finestra del browser, o controllare la compilazione di un modulo segnalando eventuali errori prima che i dati vengano spediti al server. Per svolgere tutti questi compiti, JavaScript deve essere eseguito sul sistema dell'utente: per questo il codice JavaScript viene spedito al browser insieme al codice html. Quindi l'utente ha la possibilità di visualizzarlo, contrariamente a ciò che accade con PHP.

Il server si basa sull'estensione delle pagine richieste.

In realtà il server deve essere istruito per poter fare ciò: generalmente gli si dice di eseguire PHP per le pagine che hanno estensione .php e .php3.


AddType application/x-httpd-php .php .php3 .php4

AddType application/x-httpd-php-source .phps




PHP e HTML



PHP è un linguaggio la cui funzione fondamentale è quella di produrre codice HTML. Essendo PHP è un linguaggio di programmazione, abbiamo la possibilità di analizzare diverse situazioni (l'input degli utenti, i dati contenuti in un database) e di decidere, di conseguenza, di produrre codice HTML condizionato ai risultati dell'elaborazione. Questo è, in parole povere, il Web dinamico.


La prima cosa da sapere è come fa l'interprete a riconoscere il codice php contenuto nel file che sta analizzando. Il codice deve essere compreso fra appositi tag di apertura e di chiusura, che sono i seguenti:


<?php //tag di apertura
?> //tag di chiusura


Tutto ciò che è contenuto fra questi tag deve corrispondere alle regole sintattiche del PHP, ed è codice che sarà eseguito dall'interprete e non sarà inviato al browser. Per generare il codice da inviare al browser abbiamo due costrutti del linguaggio, che possiamo considerare equivalenti, che sono: print() e echo().
Vediamo un primo esempio:


<HTML>
<HEAD>
<TITLE>Pagina di prova in PHP</TITLE>
</HEAD>
<BODY>
<?php
print("Buongiorno a tutti!<br>\n");
echo("E' una bellissima giornata");
?>
</BODY>


Questo codice produrrà un file HTML il cui contenuto sarà semplicemente:


<HTML>
<HEAD>
<TITLE>Pagina di prova in PHP</TITLE>
</HEAD>
<BODY>
Buongiorno a tutti!<br>
E' una bellissima giornata
</BODY>


E quindi l'utente vedrà sul suo browser le due righe "Buongiorno a tutti!" ed "E' una bellissima giornata".

Poco fa abbiamo visto che i comandi print() ed echo() hanno un funzionamento pressoché identico. In realtà ci sono alcune cose da puntualizzare: intanto, nessuno dei due richiede obbligatoriamente le parentesi intorno alla stringa di output. Avremmo quindi potuto scrivere


print "Buongiorno a tutti!<br>\n";
echo "E' una bellissima giornata";


e sarebbe stato ugualmente corretto. Inoltre al comando echo possono essere date in input più stringhe, separate da virgole, così:


echo "Buongiorno a tutti!", "<br>\n", "E' una bellissima giornata";


Il risultato sarebbe stato lo stesso dell'esempio precedente; in questo caso, però, non devono essere usate le parentesi.

NB: chi vuole avvicinarsi al PHP deve già avere una conoscenza di HTML e di tutto quanto può far parte di una pagina web (JavaScript, CSS eccetera) in quanto scopo di PHP è la produzione di questi codici.



Sintassi generale del linguaggio



Abbiamo a disposizione una coppia di tag per l'apertura e la chiusura del codice php contenuto in un file richiesto da un web server. Si tratta dei tag


<?php ..... ?>




Esistono anche sintassi alternative: la prima è il classico tag <script> con la specificazione del linguaggio php:

<script language="php">
.......
</script>




Un'altra è di usare i tag brevi:

<? .... ?>


Questa possibilità però è condizionata ad una impostazione del file di configurazione di PHP, php.ini (di default, i tag brevi sono abilitati). Un'ultima possibilità è quella di usare i tag in "stile ASP":


<% .... %>


Anche questi però devono essere abilitati in php.ini e, contrariamente a quelli brevi, di default non lo sono.

Tutto ciò che sta fuori da questi tag non verrà toccato da PHP, che si limiterà a passarlo al browser così com'è.



I commenti e la loro importanza



Chi ha esperienza di programmazione sa bene i commenti sono fondamentali quando si tratta di mettere le mani su un programma realizzato da qualcun altro, e anche in fase di revisione del nostro stesso codice.

Si noti che l'utilizzo dei commenti non appesantisce l'esecuzione dello script (l'interprete PHP salta tutte le parti che riconosce come commenti), né il trasferimento della pagina al browser.

Abbiamo tre diverse possibilità : la prima è l'uso dei commenti in stile C++, caratterizzati da due barre:


// Commento in stile C++


La seconda sono i commenti in stile Perl, contraddistinti dall'uso del cancelletto:


# Commento in stile Perl


Entrambi questi tipi di commenti sono limitati ad una sola riga.
Questo ci permette di porre il commento anche sulla stessa riga del codice, così:


print ('Buongiorno a tutti<br>'); //stampo un messaggio di saluto
print ('Esclusi quelli antipatici'); # faccio una precisazione
// Questa riga contiene solo commento


Il terzo tipo di commento (in stile C) prevede un codice di apertura e un codice di chiusura, e ci permette quindi di estendere il commento su più righe: inizia con una barra seguita da un asterisco, e termina con un asterisco seguito da una barra:


print ('Buonasera<br>'); /* Questo è un commento in stile C,
che può occupare più righe ma deve essere chiuso
con l'apposito simbolo */


La scelta di quale tipo di commento utilizzare è puramente soggettiva, e dipende esclusivamente dalle nostre preferenze personali.

Le variabili



Possiamo immaginare una variabile come un contenitore all'interno del quale viene conservato il valore che ci interessa, e che può cambiare di volta in volta.

In PHP possiamo scegliere il nome delle variabili usando lettere, numeri e underscore (_). Il primo carattere del nome deve essere però una lettera o un underscore.
Sono case-sensitive.
Nello script PHP il nome delle variabili è preceduto dal simbolo del dollaro ($).

PHP non richiede che le variabili vengano dichiarate prima del loro uso. Possiamo quindi riferirci ad una variabile direttamente con la sua valorizzazione:


$a = 5;



Vediamo ora qualcosa di leggermente più complesso eseguito con le variabili:


$a = 9;
$b = 4;
$c = $a * $b;




Un accenno alle variabili dinamiche: ia volte può presentarsi la necessità di utilizzare delle variabili senza sapere a priori come si chiamano. In questi casi, il nome di queste variabili sarà contenuto in ulteriori variabili. Facciamo un esempio: col codice seguente stamperemo a video il contenuto delle variabili 'pippo', 'pluto' e 'paperino':


$pippo = 'gawrsh!';
$pluto = 'bau!';
$paperino = 'quack!';
$nome = 'pippo';
print ($$nome.'<br>');
$nome = 'pluto';
print ($$nome.'<br>');
$nome = 'paperino';
print ($$nome.'<br>');


Il risultato sul browser sarà 'gawrsh!', 'bau!' e 'quack!', ciascuno sulla propria riga . Il doppio segno del dollaro ci permette infatti di usare la variabile 'nome' come contenitore del nome della variabile di cui vogliamo stampare il valore. In pratica, è come se avessimo detto a PHP: "stampa il valore della variabile che si chiama come il valore della variabile 'nome'". Questo era un esempio banale, e l'uso delle variabili dinamiche era in realtà perfettamente inutile, in quanto sapevamo benissimo come si chiamavano le variabili che ci interessavano. Però in situazioni reali può capitare di trovarsi in un ambito nel quale non sappiamo come si chiamano le variabili, e dobbiamo usare altre variabili per ricavarne il nome, oltreché il valore.






I tipi di variabile



Vediamo quali sono i tipi di valore che una variabile può contenere.

Valore booleano. Le variabili booleane sono le più semplici: il loro valore può essere TRUE o FALSE (vero o falso).


$vero = TRUE;
$falso = FALSE;


Intero. Un numero intero, positivo o negativo, il cui valore massimo (assoluto) può variare in base al sistema operativo su cui gira PHP, ma che generalmente si può considerare, per ricordarlo facilmente, di circa 2 miliardi (2 elevato alla 31esima potenza).


$int1 = 129;
$int2 = -715;
$int3 = 5 * 8; //$int3 vale 40


Virgola mobile. Un numero decimale (a volte citato come "double" o "real"). Attenzione: per indicare i decimali non si usa la virgola, ma il punto! Anche in questo caso la dimensione massima dipende dalla piattaforma. Normalmente comunque si considera un massimo di circa 1.8e308 con una precisione di 14 cifre decimali. Si possono utilizzare le seguenti sintassi:


$vm1 = 4.153; // 4,153
$vm2 = 3.2e5; // 3,2 * 10^5, cioè 320.000
$vm3 = 4E-8; // 4 * 10^-8, cioè 4/100.000.000 = 0,00000004


Stringa. Una stringa è un qualsiasi insieme di caratteri, senza limitazione. Le stringhe possono essere espresse in tre maniere:

Le stringhe delimitate da apici sono la forma più semplice, consigliata quando all'interno della stringa non vi sono variabili di cui vogliamo ricavare il valore:


$frase = 'Anna disse: "Ciao a tutti!" ma nessuno rispose';
print $frase;


Questo codice stamperà la frase: 'Anna disse: "Ciao a tutti!" ma nessuno rispose'.

Le virgolette ci consentono di usare le stringhe in una maniera più sofisticata, in quanto, se all'interno della stringa delimitata da virgolette PHP riconosce un nome di variabile, lo sostituisce con il valore della variabile stessa (si dice in questo caso che la variabile viene risolta).


$nome = 'Anna';
print "$nome è simpatica... a pochi"; /*stampa: Anna è simpatica... a pochi*/
print '$nome è simpatica... a pochi'; /*stampa: $nome è simpatica... a pochi*/



Ci sono un paio di regole molto importanti da ricordare quando si usano le stringhe delimitate da apici o virgolette: per indicate a PHP che un carattere fa parte della stringa e non è il suo delimitatore si usa il cosiddetto 'carattere di escape', cioè la barra rovesciata (backslash: \). Vediamo alcuni esempi:


print 'Torniamo un\'altra volta'; //stampa: Torniamo un'altra volta
print "Torniamo un'altra volta"; //stampa: Torniamo un'altra volta
print "Torniamo un\'altra volta"; //stampa: Torniamo un\'altra volta
print 'Torniamo un'altra volta'; /*causa un errore, perché l'apostrofo viene scambiato per l'apice di chiusura*/
print 'Anna disse "Ciao" e se ne andò'; /*stampa: Anna disse "Ciao" e se ne andò*/
print "Anna disse \"Ciao\" e se ne andò"; /*stampa: Anna disse "Ciao" e se ne andò*/
print 'Anna disse \"Ciao\" e se ne andò'; /*stampa: Anna disse \"Ciao\" e se ne andò*/
print "Anna disse "Ciao" e se ne andò"; //errore


Da questi esempi si può capire che il backslash deve essere utilizzato come carattere di escape quando vogliamo includere nella stringa lo stesso tipo di carattere che la delimita; se mettiamo un backslash davanti alle virgolette in una stringa delimitata da apici (o viceversa), anche il backslash entrerà a far parte della stringa stessa, come si vede nel terzo e nel settimo esempio. Il backslash viene usato anche come 'escape di sé stesso', nei casi in cui vogliamo esplicitamente includerlo nella stringa:


print ("Questo: \"\\\" è un backslash"); /*stampa: Questo: "\" è un backslash*/
print ('Questo: \'\\\' è un backslash'); /*stampa: Questo: '\' è un backslash*/
print ("Questo: '\' è un backslash"); /*stampa: Questo: '\' è un backslash*/
print ("Questo: '\\' è un backslash"); /*stampa: Questo: '\' è un backslash*/



Negli ultimi due casi non è necessario fare l'escape del backslash, in quanto il backslash che vogliamo stampare non può essere scambiato per un carattere di escape (infatti vicino ad esso ci sono degli apici, che in una stringa delimitata da virgolette non hanno bisogno di escape). Di conseguenza, fare o non fare l'escape del backslash in questa situazione è la stessa cosa, e difatti i due esempi forniscono lo stesso risultato.

Esaminiamo l'ultimo modo di rappresentare le stringhe: la sintassi heredoc. Questa ci consente di delimitare una stringa con i caratteri <<< seguiti da un identificatore (in genere si usa 'EOD', ma è solo una convenzione: è possibile utilizzare qualsiasi stringa composta di caratteri alfanumerici e underscore, di cui il primo carattere deve essere non numerico: la stessa regola dei nomi di variabile). Tutto ciò che segue questo delimitatore viene considerato parte della stringa, fino a quando non viene ripetuto l'identificatore seguito da un punto e virgola. Attenzione: l'identificatore di chiusura deve occupare una riga a sé stante, deve iniziare a colonna 1 e non deve contenere nessun altro carattere (nemmeno spazi vuoti) dopo il punto e virgola.


$nome = "Paolo";
$stringa = <<<EOD
Il mio nome è $nome
EOD;
print $stringa;


Questo codice stamperà 'Il mio nome è Paolo'. Infatti la sintassi heredoc risolve i nomi di variabile così come le virgolette. Rispetto a queste ultime, con questa sintassi abbiamo il vantaggio di poter includere delle virgolette nella stringa senza farne l'escape:


$frase = "ciao a tutti";
$stringa = <<<EOT
Il mio saluto è "$frase"
EOT;
print $stringa;


In questo caso stamperemo 'Il mio saluto è "ciao a tutti"'.

Array. Possiamo considerare un array (vettore) come una variabile complessa, che contiene cioè non un solo valore, ma una serie di valori, ciascuno dei quali caratterizzato da una chiave, o indice. Facciamo un primo esempio, definendo un array composto di cinque valori:


$colori = array('bianco', 'nero', 'giallo', 'verde', 'rosso');


A questo punto ciascuno dei nostri cinque colori è caratterizzato da un indice numerico, che PHP assegna automaticamente a partire da 0. L'indice viene indicato fra parentesi quadre dietro al nome dell'array:


print $colori[1]; //stampa 'nero'
print $colori[4]; //stampa 'rosso'



Oggetto. L'uso degli oggetti si rifà alla programmazione ad oggetti, e va al di là degli scopi di questa lezione.

Eliminare una variabile. In alcune situazioni ci può capitare di avere la necessità di eliminare una variabile: in questo caso PHP ci mette a disposizione l'istruzione unset():


unset($variabile);




Gli array



Un array (o vettore) è una variabile "complessa", cioè che contiene molteplici valori invece di uno solo. Abbiamo visto una prima maniera per definire un array, elencando i suoi valori separati da virgole:


$colori = array('bianco', 'nero', 'giallo', 'verde', 'rosso');


Usando questo tipo di definizione, PHP associa a ciascuno dei valori che abbiamo elencato un indice numerico, a partire da 0. Quindi, in questo caso, 'bianco' assumerà l'indice 0, 'nero' l'indice 1, e così via fino a 'rosso' che avrà indice 4. Per riferirsi ad un singolo elemento dell'array si indica il nome dell'array seguito dall'indice contenuto fra parentesi quadre:


print $colori[2]; //stampa 'giallo'


Esiste poi un metodo per aggiungere un valore all'array; questo metodo può essere usato anche, come alternativa al precedente, per definire l'array:


$colori[] = 'blu';


Con questo codice verrà creato un nuovo elemento nell'array $colori, che avrà l'indice 5. Questa sintassi infatti può essere "tradotta" come "aggiungi un elemento in fondo all'array $colori".
Se l'array $colori non fosse ancora definito, questa istruzione lo avrebbe definito creando l'elemento con indice 0. E' naturalmente possibile anche indicare direttamente l'indice: ad esempio


$colori[3] = 'arancio';
$colori[7] = 'viola';


Dopo questa istruzione, l'elemento con indice 3, che prima valeva 'verde', avrà il valore cambiato in 'arancio'. Inoltre avremo un nuovo elemento, con indice 7, con il valore 'viola'. E' da notare che, dopo queste istruzioni, il nostro array ha un "buco", perché dal codice 5 si salta direttamente al codice 7: successivamente, se useremo di nuovo l'istruzione di "incremento" con le parentesi quadre vuote, il nuovo elemento prenderà l'indice 8. Infatti PHP, quando gli proponiamo un'istruzione di quel tipo, va a cercare l'elemento con l'indice più alto, e lo aumenta di 1 per creare quello nuovo.

Ma l'argomento array non si limita a questo: infatti gli indici degli elementi non sono necessariamente numerici. Possono essere anche delle stringhe:


$persona['nome'] = 'Mario';


Con questa istruzione abbiamo definito un array di nome $persona, creando un elemento la cui chiave è 'nome' ed il cui valore è 'Mario'.

PHP gestisce un unico tipo di array, le cui chiavi possono essere numeriche o associative che possono coesistere nello stesso array. Vediamo un esempio banale, ipotizzando la formazione di una squadra di calcio:


$formazione[1] ='Buffon';
$formazione[2] ='Panucci';
$formazione[3] ='Nesta';
$formazione[4] ='Cannavaro';
$formazione[5] ='Coco';
$formazione[6] ='Ambrosini';
$formazione[7] ='Tacchinardi';
$formazione[8] ='Perrotta';
$formazione[9] ='Totti';
$formazione[10] ='Inzaghi';
$formazione[11] ='Vieri';
$formazione['ct'] = 'Trapattoni';


In questo caso abbiamo creato un array con dodici elementi, di cui undici con chiavi numeriche, ed uno con chiave associativa. Se in seguito volessimo aggiungere un elemento usando le parentesi quadre vuote, il nuovo elemento prenderà l'indice 12. Avremmo potuto creare lo stesso array usando l'istruzione di dichiarazione dell'array, così:


$formazione = array(1 => 'Buffon', 'Panucci', 'Nesta', 'Cannavaro', 'Coco', 'Ambrosini', 'Tacchinardi', 'Perrotta', 'Totti', 'Inzaghi', 'Vieri', 'ct' => 'Trapattoni');


Analizziamo il formato di questa istruzione: per prima cosa abbiamo creato il primo elemento, assegnandogli esplicitamente la chiave 1. Come possiamo vedere, il sistema per fare ciò è di indicare la chiave, seguita dal simbolo "=>" (uguale + maggiore) e dal valore dell'elemento. Se non avessimo indicato 1 come indice, PHP avrebbe assegnato al primo elemento l'indice 0. Per gli elementi successivi, ci siamo limitati ad elencare i valori, in quanto PHP, per ciascuno di essi, crea la chiave numerica aumentando di 1 la più alta già esistente. Quindi 'Panucci' prende l'indice 2, 'Nesta' il 3 e così via. Arrivati all'ultimo elemento, siccome vogliamo assegnargli una chiave associativa, siamo obbligati ad indicarla esplicitamente.

Vediamo ora in che modo possiamo creare strutture complesse di dati, attraverso gli array a più dimensioni.

Un array a più dimensioni è un array nel quale uno o più elementi sono degli array a loro volta. Supponiamo di voler raccogliere in un array i dati anagrafici di più persone: per ogni persona registreremo nome, cognome, data di nascita e città di residenza


$persone = array( array('nome' => 'Mario', 'cognome' => 'Rossi', 'data_nascita' => '1973/06/15', 'residenza' => 'Roma'), array('nome' => 'Paolo', 'cognome' => 'Bianchi', 'data_nascita' => '1968/04/05', 'residenza' => 'Torino'), array('nome' => 'Luca', 'cognome' => 'Verdi', 'data_nascita' => '1964/11/26', 'residenza' => 'Napoli'));
print $persone[0]['cognome']; // stampa 'Rossi'
print $persone[1]['residenza']; // stampa 'Torino'
print $persone[2]['nome']; // stampa 'Luca'


Con questo codice abbiamo definito un array formato a sua volta da tre array, che sono stati elencati separati da virgole, per cui ciascuno di essi ha ricevuto l'indice numerico a partire da 0. All'interno dei singoli array, invece, tutte le chiavi sono state indicate come associative. Da notare che, sebbene in questo caso ciascuno dei tre array 'interni' abbia la stessa struttura, in realtà è possibile dare a ciascun array una struttura autonoma. Vediamo un altro esempio:


$persone = array( 1 => array('nome' => 'Mario Rossi', 'residenza' => 'Roma', 'ruolo' => 'impiegato'), 2 => array('nome' => 'Paolo Bianchi', 'data_nascita' => '1968/04/05', 'residenza' => 'Torino'), 'totale_elementi' => 2);
print $persone[1]['residenza']; // stampa 'Roma'
print $persone['totale_elementi']; // stampa '2'


In questo caso il nostro array è formato da due array, ai quali abbiamo assegnato gli indici 1 e 2, e da un terzo elemento, che non è un array ma una variabile intera, con chiave associativa 'totale_elementi'. I due array che costituiscono i primi due elementi hanno una struttura diversa: mentre il primo è formato dagli elementi 'nome', 'residenza' e 'ruolo', il secondo è formato da 'nome', 'data_nascita' e 'residenza'.

Contare gli elementi di un array. Se vogliamo sapere di quanti elementi è composto un array, possiamo utilizzare la funzione count():


$numero_elementi = count($formazione);


Nell'esempio visto prima, la variabile $numero_elementi assumerà il valore 12: infatti abbiamo 11 elementi con chiavi numeriche e 1 ('ct') con la chiave associativa.
Eliminare un intero array o soltanto un suo elemento.


unset($colori[2]); // elimina l'elemento 'giallo'
unset($formazione); // elimina l'intero array $formazione


Con la prima di queste due istruzioni abbiamo eliminato l'elemento con chiave 2 dall'array $colori. Questo creerà un 'buco' nell'array, che passerà così dall'elemento 1 all'elemento 3. Con la seconda istruzione invece eliminiamo l'intero array $formazione.




Gli operatori



Gli operatori consentono di manipolare il contenuto delle nostre variabili. Il conosciuto degli operatori è quello di assegnazione:


$nome = 'Giorgio';


Il simbolo '=' serve infatti ad assegnare alla variabile $nome il valore 'Giorgio'. In generale, possiamo dire che con l'operatore di assegnazione prendiamo ciò che sta alla destra del segno '=' ed assegnamo lo stesso valore a ciò che sta a sinistra.

Altri operatori molto facili da comprendere sono quelli aritmetici: addizione, sottrazione, divisione, moltiplicazione, modulo.


$a = 3 + 7; //addizione
$b = 5 - 2; //sottrazione
$c = 9 * 6; //moltiplicazione
$d = 8 / 2; //divisione
$e = 7 % 4; /*modulo (il modulo è il resto della divisione, quindi in questo caso 3)*/


Uno degli operatori più utilizzati è quello che serve per concatenare le stringhe: il punto.


$nome = 'pippo';
$stringa1 = 'ciao ' . $nome; //$stringa1 vale 'ciao pippo'


Con l'operatore di assegnazione si può anche usare una variabile per effettuare un calcolo il cui risultato deve essere assegnato alla variabile stessa. Ad esempio, supponiamo di avere una variabile di cui vogliamo aumentare il valore:


$a = $a + 10; //il valore di $a aumenta di 10


Con questa istruzione, viene eseguito il calcolo che sta alla destra del segno '=' ed il risultato viene memorizzato nella variabile indicata a sinistra. Quindi è chiaro che il valore di tale variabile prima dell'istruzione viene utilizzato per il calcolo, ma dopo che l'istruzione è stata eseguita questo valore è cambiato. Un risultato di questo tipo si può ottenere anche con gli operatori di assegnazione combinati, che ci permettono di 'risparmiare' sul codice:


$x += 4; //incrementa $x di 4 (equivale a $x = $x + 4)
$x -= 3; //decrementa $x di 3 (equivale a $x = $x - 3)
$x .= $a; /*il valore della stringa $a viene concatenato a $x (equivale a $x = $x . $a)*/
$x /= 5; //equivale a $x = $x / 5
$x *= 4; //equivale a $x = $x * 4
$x %= 2; //equivale a $x = $x % 2


Il terzo (l'operatore di concatenamento) è probabilmente il più usato di tutti, perché risulta molto utile quando abbiamo bisogno di costruire stringhe piuttosto lunghe. Anche i primi due possono essere utilizzati in determinate situazioni. Fra l'altro, per quanto riguarda incremento e decremento abbiamo altri operatori ancora più sintetici che si possono utilizzare per incrementare o decrementare i valori di una unità:


$a++; /*incrementa di 1: equivale ad $a = $a + 1, o $a += 1*/
++$a; /*stessa cosa, ma con una differenza nella valutazione dell'espressione (v. lezione 11 sulle espressioni)*/
$a--; //decrementa di 1: equivale ad $a = $a - 1, o $a -= 1
--$a; //anche qui stessa cosa, con la stessa differenza di cui sopra


Gli operatori di confronto. Quando utilizziamo gli operatori di confronto, confrontiamo i due valori posti a sinistra e a destra dell'operatore stesso. Il risultato di questa operazione sarà, ogni volta, vero (true) o falso (false). Questi operatori sono:

Vediamo alcuni esempi:


$a = 7; $b = 7.0; $c = 4; //assegnamo valori a tre variabili
$a == $b; //vero
$a == $c; //falso
$a === $b; //falso, perché $a è intero mentre $b è float
$a > $c; //vero
$c >= $a; //falso, $c è minore di $a
$a < $b; //falso, hanno lo stesso valore
$c <= $b; //vero


Una piccola osservazione sul terzo confronto: siccome abbiamo assegnato il valore di $b usando la notazione col punto decimale, per PHP $b è una variabile del tipo in virgola mobile, anche se in realtà il suo valore è intero. Per questo il confronto di identità restituisce falso.

Confronti tra stringhe

In questo caso il confronto viene fatto basandosi sull'ordine alfabetico dei caratteri: vale a dire che vengono considerati 'minori' i caratteri che 'vengono prima' nell'ordine alfabetico. Quindi 'a' è minore di 'b', 'b' è minore di 'c', eccetera. Inoltre tutte le lettere minuscole sono 'maggiori' delle lettere maiuscole, e tutte, maiuscole e minuscole, sono 'maggiori' delle cifre da 0 a 9:


$a = 'Mario'; $b = 'Giorgio'; $c = 'Giovanni'; $d = 'antonio'; $e = '4 gatti';
$a < $b; //falso, la 'G' precede la 'M'
$b < $c; //vero, la 'r' ('Gior') precede la 'v' ('Giov')
$d > $a; /*vero, la 'a' minuscola è 'maggiore' di qualsiasi lettera maiuscola*/
$c > $e; //vero, ogni lettera è 'maggiore' di qualsiasi cifra




Gli operatori logici. Con gli operatori logici possiamo combinare più valori booleani, oppure negarne uno (nel caso di NOT). Questi valori sono:

Vediamo qualche esempio:


10 > 8 And 7 < 6; /*falso, perché la prima condizione è vera ma la seconda è falsa*/
10 > 8 Or 7 < 6; //vero
9 > 5 And 5 == 5; //vero: entrambe le condizioni sono vere
9 > 5 Xor 5 == 5; /*falso: solo una delle due deve essere vera perché si verifichi lo 'Xor'*/
4 < 3 || 7 > 9; //falso: nessuna delle due condizioni è vera
6 == 6 && 1 > 4; //falso: solo la prima condizione è vera


Per quanto riguarda gli operatori 'and' e 'or', le due diverse notazioni differiscono per il livello di precedenza in caso di espressioni complesse.

Vediamo quindi qual è l'ordine di priorità dei diversi operatori, iniziando da quelli che hanno la priorità maggiore:

  1. Operatori di incremento e decremento (++ --)

  2. Moltiplicazione, divisione, modulo (* / %)

  3. Addizione e sottrazione (+ -)

  4. Operatori di confronto per minore e maggiore (< <= => >)

  5. Operatori di confronto per uguaglianza e disuguaglianza (== === !=)

  6. Operatore logico 'and', nella notazione col simbolo (&&)

  7. Operatore logico 'or', nella notazione col simbolo (||)

  8. Operatori di assegnazione, compresi quelli 'sintetici' (= += -= /= *= %= .=)

  9. Operatore logico 'and', nella notazione letterale (And)

  10. Operatore logico 'xor' (Xor)

  11. Operatore logico 'or', nella notazione letterale (Or)

Abbiamo già visto prima, in occasione degli esempi sugli operatori logici, l'applicazione di questi principi di precedenza: infatti in tutte quelle espressioni venivano valutati prima gli operatori di confronto e, solo dopo, quelli logici. Un'altra classica rappresentazione di esempio è quella dell'espressione algebrica:


5 + 4 * 2; /*questa espressione vale 13 e non 18, perché la moltiplicazione viene eseguita prima*/
(5 + 4) * 2; /*questa invece vale 18, perché le parentesi modificano l'ordine di esecuzione*/


Come abbiamo visto, così come avviene in algebra, usando le parentesi possiamo determinare a nostro piacere quali operatori devono essere valutati per primi.
Hint: usare le parentesi sempre in espressioni complesse.





Le espressioni



Possiamo definire un'espressione come una qualsiasi combinazione di funzioni, valori e operatori che si risolvono in un valore. Nel caso visto prima, l'espressione 7+3 ha come valore 10.

In generale, in PHP, qualsiasi cosa utilizzabile come un valore può essere considerata un'espressione. Vediamo alcuni rapidi esempi:


15 * 3; //espressione il cui valore è 45
'Giacomo' . ' Verdi'; //espressione il cui valore è 'Giacomo Verdi'
$a + $b; /*espressione il cui valore è dato dalla somma dei valori delle variabili $a e $b*/


Come possiamo vedere, quindi, la presenza di operatori fa sì che il valore dell'espressione risulti diverso da quello dei singoli valori che fanno parte dell'espressione stessa. Vediamo un caso particolare, quello dell'operatore di assegnazione:


$a = 6; //il valore di questa espressione è 6


Quando usiamo una espressione per assegnare un valore ad una variabile, il valore che tale espressione assume è uguale a quello che si trova a destra dell'operatore di assegnazione (che è anche quello che viene assegnato all'operatore di sinistra). Questo significa che noi possiamo scrivere


print ('Paolo'); //stampa 'Paolo'
print ($nome = 'Paolo'); //stampa sempre 'Paolo'


Le due espressioni hanno infatti lo stesso valore, cioè 'Paolo'. Quindi con le due istruzioni viste sopra otteniamo sul browser lo stesso risultato. La differenza, ovviamente, è che con la seconda, oltre a stampare il valore a video, abbiamo anche assegnato lo stesso valore alla variabile $nome.

Vediamo qualche altro esempio:


7 > 4; //valore dell'espressione: true (vero)
$a = 7 > 4; /*valore dell'espressione: lo stesso di prima; la variabile $a assume quindi il valore true*/
$b = 5 * 4; //valore dell'espressione: 20; viene assegnato a $b


Nella lezione sugli operatori avevamo accennato ad una differenza nella valutazione dell'espressione fra i diversi modi di utilizzare gli operatori di incremento e di decremento. Vediamo ora di approfondire questo concetto:


$a = 10; $b = 10;
++$a; //incrementiamo $a, che diventa 11; l'espressione vale 11
$b++; //anche $b diventa 11; qui però l'espressione vale 10


La differenza è questa: se usiamo l'operatore di incremento (o di decremento) prima della variabile, l'espressione assume il nuovo valore della variabile stessa. Se invece lo mettiamo dopo, l'espressione prenderà il valore che la variabile aveva prima dell'operazione. Di conseguenza:


$a = 5; $b = 5;
print ++$a; //$a diventa 6, e viene stampato '6'
print $b++; //anche $b diventa 6, ma viene stampato '5'
print ++$b; //a questo punto $b è diventato 7, e viene stampato '7'


Normalmente è bene evitare di addentrarsi in queste sottigliezze, per non rendere il nostro codice difficilmente comprensibile a chi lo legge. In genere gli operatori di incremento vengono utilizzati in espressioni che hanno l'unica funzione di modificare il valore dell'operando, in modo che non ci siano dubbi sul loro significato. Ovviamente, in questo caso, utilizzare una notazione piuttosto che l'altra non comporta alcuna differenza.


Strutture di controllo: condizioni



Le strutture di controllo permettono di eseguire operazioni diverse, anche più volte, in base alla valutazione di determinate condizioni.

La principale di queste istruzioni è la 'if', la cui sintassi più elementare è la seguente:


if ($nome == 'Luca')
print "ciao Luca!<br>";


Dopo l'if, deve essere indicata fra parentesi un'espressione da valutare (condizione). Questa espressione verrà valutata in senso booleano. Nel caso in cui l'espressione non abbia un valore booleano, PHP convertirà comunque questo valore in booleano. Dunque, se la condizione è vera, l'istruzione successiva viene eseguita. In caso contrario, viene ignorata. Potremmo anche avere la necessità di eseguire, nel caso in cui la condizione sia vera, non una sola ma più istruzioni. Questo è perfettamente possibile, comprendendo il blocco di istruzioni fra due parentesi graffe, ad esempio così:


if ($nome == 'Luca') {
print "ciao Luca!<br>";
print "dove sono i tuoi amici?<br>";
}
print "ciao a tutti voi";


In questo modo, se la variabile $nome ha effettivamente il valore 'Luca' vengono eseguite le due istruzioni successive, comprese fra le parentesi graffe. Dopo avere valutato la condizione ed eventualmente eseguito le due istruzioni previste, lo script proseguirà con ciò che sta fuori dalle parentesi graffe. Quindi nel nostro esempio la frase "ciao a tutti voi" viene prodotta in ogni caso. E' buona norma usare comunque le parentesi graffe per delimitare il codice condizionato, anche quando è costituito da una sola istruzione: infatti questo rende il codice più leggibile.

NB: in questo costrutto mancano i punto e virgola. Infatti la 'if' e la condizione espressa fra parentesi non devono averli; continuiamo invece a metterli nel blocco di codice condizionato.



Abbiamo detto poco fa che la condizione espressa fra parentesi potrebbe non avere un valore booleano. PHP però è in grado di considerare booleano qualsiasi valore, in base ad una regola molto semplice. Facciamo un altro esempio banale:


if (5) {
print "ciao Luca!";
}


Questo codice, da un punto di vista logico, non ha nessun senso, ma ci permette di capire come PHP interpreta le nostre espressioni. Infatti in questo caso la stringa "ciao Luca!" verrà sempre stampata. Questo perché, per PHP, il valore 5, così come qualsiasi numero diverso da 0, è considerato 'vero'.

PHP considera come falsi:

Qualsiasi altro valore, per PHP è un valore vero.

Provate questo ;)


$a = 7;
if ($a = 4)
print '$a è uguale a 4!';



NB: quando vogliamo verificare se il valore di una variabile è uguale a qualcosa, di utilizzare l'operatore condizionale di uguaglianza, cioè il doppio uguale ("=="). In caso contrario, non solo otterremo molto spesso risultati diversi da quelli che ci saremmo aspettati, ma avremo anche modificato il valore di una variabile che volevamo soltanto verificare!

Continuiamo l'analisi dell'istruzione 'if': ci permette non solo di indicare quali istruzioni vogliamo eseguire se la condizione è vera, ma anche di esprimere un blocco di codice da eseguire quando la condizione è falsa. Ecco come:


if ($nome == 'Luca') {
print "bentornato Luca!";
} else {
print "ciao $nome!";
}


La parola chiave 'else', che significa 'altrimenti', deve essere posizionata subito dopo la parentesi graffa di chiusura del codice previsto per il caso 'vero' (o dopo l'unica istruzione prevista, se non abbiamo usato le graffe). Anche per 'else' valgono le stesse regole: niente punto e virgola, parentesi graffe obbligatorie se dobbiamo esprimere più di un'istruzione, altrimenti facoltative. Ovviamente il blocco di codice specificato per 'else' viene ignorato quando la condizione è vera, mentre viene eseguito se la condizione è falsa.

Le istruzioni 'if' possono essere nidificate una dentro l'altra, consentendoci così di creare codice di una certa complessità. Esempio:


if ($nome == 'Luca') {
if ($cognome == 'Rossi') {
print "Luca Rossi è di nuovo fra noi";
} else {
print "Abbiamo un nuovo Luca!";
}
} else {
print "ciao $nome!";
}


In questo caso, abbiamo nidificato un ulteriore test all'interno del primo caso, quello in cui $nome ha il valore 'Luca'. Abbiamo infatti previsto un messaggio diverso, a seconda del valore della variabile $cognome.
Un'ulteriore possibilità che ci fornisce l'istruzione 'if' in PHP è quella di utilizzare la parola chiave 'elseif'. Attraverso questa possiamo indicare una seconda condizione, da valutare solo nel caso in cui la prima sia falsa. Indicheremo quindi, di seguito, il codice da eseguire nel caso in cui questa condizione sia vera, ed eventualmente, con 'else', il codice previsto per il caso in cui anche la seconda condizione è falsa.


if ($nome == 'Luca') {
print "bentornato Luca!";
} elseif ($cognome == 'Verdi') {
print "Buongiorno, signor Verdi";
} else {
print "ciao $nome!";
}


In questo caso, abbiamo un'istruzione da eseguire quando $nome vale 'Luca'; nel caso in cui ciò non sia vero, è prevista una seconda istruzione se $cognome è 'Verdi'; se nemmeno questo è vero, allora verrà eseguita la terza istruzione. Da notare che, se $nome è 'Luca' e $cognome è 'Verdi', viene comunque eseguita solo la prima istruzione, perché dopo avere verificato la condizione, tutti gli altri casi vengono saltati.

Passiamo ora a verificare una seconda istruzione che ci permette di prevedere diversi valori possibili per un'espressione:


switch ($nome) {
case 'Luca':
print "E' tornato Luca!";
break;
case 'Mario':
print "Ciao, Mario!";
break;
case 'Paolo':
print "Finalmente, Paolo!";
break;
default:
print "Benvenuto, chiunque tu sia";
}


L'istruzione 'switch' prevede che indichiamo, fra parentesi, un'espressione che verrà valutata per il suo valore (non necessariamente booleano). Di seguito, tra parentesi graffe, esprimeremo una serie di espressioni da confrontare con quella indicata prima: dal momento in cui ne trova una il cui valore è uguale, PHP esegue il codice indicato di seguito, fino a quando non incontra un'istruzione 'break'. Come possiamo vedere dall'esempio, le espressioni da confrontare con la prima vengono precedute dalla parola chiave 'case' e seguite dai due punti. L'istruzione 'default' può essere indicata come 'ultimo caso', che si considera verificato quando nessuno dei casi precedenti è risultato vero. L'indicazione 'default' può anche essere assente, ma quando c'è deve essere l'ultima della switch.
Nel nostro esempio abbiamo indicato una frase di saluto per ciascuno dei valori previsti per la variabile $nome, più una frase generica per il caso in cui il valore di $nome non sia nessuno di quelli indicati.

E' molto importante comprendere la funzione dell'istruzione break in questa situazione: infatti, quando PHP verifica uno dei casi, esegue non solo il codice che trova subito dopo, ma anche tutto quello che trova di seguito, compreso quello relativo ai casi seguenti. Questo fino a quando non trova, appunto, un'istruzione break. Nel nostro esempio, se non avessimo messo i break e il valore di $nome fosse stato 'Luca', avremmo ottenuto in output tutti e quattro i messaggi. Questo comportamento, apparentemente bizzarro, ci permette però di prevedere un unico comportamento per più valori dell'espressione sotto esame:


switch ($nome) {
case 'Luca':
case 'Giorgio':
case 'Franco':
print "Ciao, vecchio amico!";
break;
case 'Mario':
print "Ciao, Mario!";
break;
case 'Paolo':
print "Finalmente, Paolo!";
break;
default:
print "Benvenuto, chiunque tu sia";
}


In questo caso, abbiamo previsto un unico messaggio per il caso in cui la variabile $nome valga 'Luca', 'Giorgio' o 'Franco'.

L'operatore ternario. L'operatore ternario è così chiamato perché è formato da tre espressioni: il valore restituito è quello della seconda o della terza di queste espressioni, a seconda che la prima sia vera o falsa. In pratica, si può considerare, in certi casi, una maniera molto sintetica di effettuare una 'if'.


($altezza >= 180) ? 'alto' : 'normale' ;


Questa espressione prenderà il valore 'alto' se la variabile $altezza è maggiore o uguale a 180, e 'normale' nel caso opposto. Come vediamo, l'espressione condizionale è contenuta fra parentesi e seguita da un punto interrogativo, mentre due punti separano la seconda espressione dalla terza. Questo costrutto può essere utilizzato, ad esempio, per valorizzare velocemente una variabile senza ricorrere all'if:


$tipologia = ($altezza >= 180) ? 'alto' : 'normale';


equivale a scrivere


if ($altezza >= 180)
$tipologia = 'alto' ;
else
$tipologia = 'normale';


Come potete vedere, in termini di spazio il risparmio è abbastanza significativo. Bisogna però stare attenti ad abusare di questa forma, perché a volte può rendere più difficoltosa la leggibilità del nostro script.



Strutture di controllo: cicli



I cicli permettono di eseguire determinate operazioni in maniera ripetitiva.
Esempio : supponiamo di voler mostrare i multipli da 1 a 10 di un numero, ad esempio 5. La prima soluzione è quella di usare il ciclo for:


for ($mul = 1; $mul <= 10; $mul++) {
$ris = 5 * $mul;
print("5 * $mul = $ris<br>");
}


Questo costrutto utilizza la parola chiave 'for', seguita, fra parentesi, dalle istruzioni per definire il ciclo; di seguito, si racchiudono fra parentesi graffe tutte le istruzioni che devono essere eseguite ripetutamente. Le tre istruzioni inserite fra le parentesi tonde vengono trattate in questo modo: la prima viene eseguita una sola volta, all'inizio del ciclo; la terza viene eseguita alla fine di ogni iterazione del ciclo; la seconda deve essere una condizione, e viene valutata prima di ogni iterazione del ciclo: quando risulta falsa, l'esecuzione del ciclo viene interrotta, ed il controllo passa alle istruzioni dopo le parentesi graffe. Quando invece è vera, le istruzioni fra parentesi graffe vengono eseguite. Ovviamente è possibile che tale condizione risulti falsa fin dal primo test: in questo caso, le istruzioni contenute fra le parentesi graffe non saranno eseguite nemmeno una volta.
Il formato standard è quindi quello che abbiamo visto sopra, che utilizza le parentesi tonde per definire un 'contatore': con la prima istruzione lo si inizializza, con la seconda lo si confronta con un valore limite oltre il quale il ciclo deve terminare, con la terza lo si incrementa dopo ogni esecuzione.

Con il ciclo 'for', così come con tutti gli altri cicli, è molto importante stare attenti a non creare una situazione in cui il ciclo non raggiunge mai una via d'uscita (il cosiddetto 'loop'): in questo caso, infatti, lo script rieseguirebbe il nostro ciclo all'infinito.
In PHP, questo di solito non succede, in quanto gli script PHP hanno un limite di tempo per la loro esecuzione, oltre il quale si arrestano. Tale limite è normalmente di 30 secondi, ed è comunque impostabile attraverso il file php.ini.

Il ciclo 'while'.

Questo si può considerare come una specie di 'if' ripetuta più volte: infatti la sua sintassi prevede che alla parola chiave 'while' segua, fra parentesi, la condizione da valutare, e fra parentesi graffe, il codice da rieseguire fino a quando tale condizione rimane vera. Vediamo con un esempio come ottenere lo stesso risultato dell'esempio precedente:


$mul = 1;
while ($mul <= 10) {
$ris = 5 * $mul;
print("5 * $mul = $ris<br>");
$mul++;
}


Il ciclo 'while', rispetto al 'for', non ci mette a disposizione le istruzioni per inizializzare e per incrementare il contatore: quindi dobbiamo inserire queste istruzioni nel flusso generale del codice, per cui mettiamo l'inizializzazione prima del ciclo, e l'incremento all'interno del ciclo stesso, in fondo.

Esiste invece un'altra forma, simile al 'while', con la quale possiamo assicurarci che il codice indicato tra le parentesi graffe venga eseguito almeno una volta: si tratta del 'do...while'


$mul = 11;
do {
$ris = 5 * $mul;
print("5 * $mul = $ris<br>");
$mul++;
} while ($mul <= 10)


Con questa sintassi, il 'while' viene spostato dopo il codice da ripetere, ad indicare che la valutazione della condizione viene eseguita solo dopo l'esecuzione del codice fra parentesi graffe. Nel caso del nostro esempio, abbiamo inizializzato la variabile $mul col valore 11, per creare una situazione nella quale, con i cicli visti prima, non avremmo ottenuto alcun output, mentre con l'uso del 'do...while' il codice viene eseguito una volta nonostante la condizione indicata fra parentesi sia falsa fin dall'inizio. L'esempio stamperà quindi "5 * 11 = 55".

Uscire da un ciclo. PHP termina l'esecuzione di un ciclo quando la condizione a cui è sottoposto non è più verificata. Abbiamo però a disposizione altri strumenti per modificare il comportamento del nostro script dall'interno del ciclo: possiamo dire a PHP di non completare la presente iterazione e passare alla successiva (con 'continue') oppure di interrompere definitivamente l'esecuzione del ciclo (con 'break'). Vediamo un esempio:


for ($ind = 1; $ind < 500; $ind++) {
if ($ind % 100 == 0) {
break;
}elseif ($ind % 25 == 0) {
continue;
}
print("valore: $ind<br>");
}


Questo codice imposta un ciclo per essere eseguito 500 volte, con valori di $ind che vanno da 1 a 500. In realtà, le istruzioni che abbiamo posto al suo interno fanno sì che la stampa del valore di $ind non venga eseguita ogni volta che $ind corrisponde ad un multiplo di 25 (infatti l'istruzione 'continue' fa sì che PHP salti la 'print' e passi direttamente all'iterazione successiva, incrementando la variabile), e che il ciclo si interrompa del tutto quando $ind raggiunge il valore 100.

Esiste un ultimo tipo di ciclo, ed è un ciclo particolare perché é costruito appositamente per il trattamento degli array: si tratta del 'foreach'. Questo ci permette di costruire un ciclo che viene ripetuto per ogni elemento dell'array che gli passiamo. La sintassi è la seguente:


foreach ($arr as $chiave => $valore) {
....istruzioni da ripetere....
}


All'interno delle parentesi graffe avremo a disposizione, nelle due variabili che abbiamo definito $chiave e $valore, l'indice e il contenuto dell'elemento che stiamo trattando. E' da notare che, nel caso ci interessi soltanto il valore e non la chiave (ad esempio perché le chiavi sono numeriche), possiamo anche evitare di estrarre la chiave stessa:


foreach ($arr as $valore) {
....istruzioni da ripetere....
}