4.Php: Strutture di Controllo
8.Strutture di controllo
			

Istruzione If

Con le strutture di controllo andiamo ad analizzare un altro degli aspetti fondamentali della programmazione: la possibilità cioè di eseguire operazioni diverse, ed eventualmente di eseguirle più volte, in base alla valutazione di determinate condizioni. In questa lezione esamineremo le istruzioni che ci permettono di eseguire o non eseguire certe porzioni di codice. If La principale di queste istruzioni è la if, la cui sintassi più elementare è la seguente: if( <condizione> ) { <codice> } Dopo l'if, deve essere indicata fra parentesi un'espressione da valutare (condizione). Questa espressione verrà valutata in senso booleano, cioè il suo valore sarà considerato vero o falso. Nel caso in cui l'espressione non abbia un valore booleano, PHP convertirà comunque questo valore in booleano utilizzando precise regole che vedremo tra qualche riga. 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, ma dobbiamo ricordarci di comprendere questo blocco di istruzioni fra due parentesi graffe, ad esempio così: // .... if ($nome == 'Luca') { echo "ciao Luca!<br>"; echo "dove sono i tuoi amici?<br>"; } echo "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. È 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, ed inoltre potrebbe evitarci degli errori se ci dovesse capitare di voler aggiungere delle istruzioni al blocco condizionato dimenticando di aggiungere le graffe. Dobbiamo notare un particolare, riguardo alla sintassi di questa istruzione: per la prima volta, vediamo che 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 alcune regole molto semplici. 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'. In sostanza, PHP considera come falsi: il valore numerico 0, nonchè una stringa che contiene '0' una stringa vuota un array con zero elementi un valore NULL, cioè una variabile che non è stata definita o che è stata eliminata con unset(), oppure a cui è stato assegnato il valore NULL esplicitamente Qualsiasi altro valore, per PHP è un valore vero. Quindi qualsiasi numero, intero o decimale purchè diverso da 0, qualsiasi stringa non vuota, se usati come espressione condizionale saranno considerati veri. Quindi anche la banale espressione che abbiamo utilizzato nell'esempio di prima. Analizziamo ora un caso che spesso crea problemi se non viene compreso fin dalle prime battute. Vediamo questo codice $a = 7; if ($a = 4) echo '$a è uguale a 4!'; A prima vista, qualcuno potrebbe essere ingannato da queste istruzioni, soprattutto chi ha precedenti esperienze di programmazione in linguaggi strutturati diversamente, nei quali un'espressione come $a = 4 potrebbe essere sia un'assegnazione che un test. Costoro infatti si aspetteranno che questo blocco di codice non stampi niente, e rimarrebbero molto sorpresi, qualora lo provassero, di vedere invece sul browser la frase '$a è uguale a 4'. Questo succederebbe perchè l'espressione che abbiamo messo fra parentesi è un'assegnazione: cioè essa assegna alla variabile $a il valore 4. L'istruzione seguente viene quindi eseguita, per il motivo che abbiamo visto prima: il valore della nostra espressione è 4, che per PHP è un valore vero. Se invece che if ($a = 4) avessimo scritto if ($a = 0) l'istruzione seguente sarebbe stata saltata, perchè la nostra condizione avrebbe preso valore 0, cioè falso. Per ottenere il risultato corretto logicamente, avremmo dovuto utilizzare l'operatore di confronto: $a = 7; if ($a == 4) echo '$a è uguale a 4!'; Ricordiamoci quindi, 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.

Istruzioni Else e Elseif

Else Andiamo ora un po' più a fondo nell'analisi dell'istruzione if: essa infatti 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 (<condizione>) { <codice> } else { <codice> } 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. Elseif 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 quella precedente risulti 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.

Istruzione Switch e operatore ternario

Switch Passiamo ora a verificare una seconda istruzione che ci permette di prevedere diversi valori possibili per un'espressione ed eseguire codice specifico in base al valore: switch (<condizione>) { case <valore 1>: <codice> break; case <valore 1>: <codice> break; .... default: <codice>; break; } L'istruzione switch prevede che indichiamo, fra parentesi, un'espressione che verrà valutata per il suo valore (questa volta non si tratta necessariamente di un valore 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. È 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. Se non mettessimo un'istruzione break alla fine di un blocco di codice relativo ad un caso particolare, l'esecuzione continuerebbe eseguendo anche il case successivo. Questo comportamento 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, anche se risulta di indubbia utilità nel caso in cui si necessiti rendere più compatto il codice.

Strutture di Ripetizione: I cicli

I cicli sono un altro degli elementi fondamentali di qualsiasi linguaggio di programmazione, in quanto ci permettono di eseguire determinate operazioni in maniera ripetitiva. È una necessità che si presenta molto spesso: infatti non è raro che un programma o uno script debbano elaborare quantità anche molto grosse di dati; in questa situazione, si prevederà il trattamento da utilizzare per ogni singolo dato (o gruppo di dati correlati), che sarà poi ripetuto per tutte le ricorrenze di tali dati. Ciclo For Iniziamo subito con un esempio (come al solito abbastanza banale): 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; echo "5 * $mul = $ris <br/>"; } Questo costrutto, simile a quello usato in altri linguaggi, 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 e separate da punto e virgola 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. Nel nostro esempio di prima potrebbe succedere, ad esempio, se sbagliassimo a scrivere il nome della variabile $mul nell'istruzione di incremento: se avessimo scritto $mus++, avremmo incrementato questa variabile, che non viene utilizzata nel ciclo, dopo ciascuna delle sue esecuzioni; in questo modo $mul rimarrebbe sempre uguale ad 1, ed il nostro ciclo stamperebbe all'infinito "5 * 1 = 5", perchè $mul non diventerebbe mai maggiore di 10. In molte situazioni classiche di programmazione, un errore di questo genere potrebbe costringerci a forzare la chiusura del programma o addirittura a spegnere la macchina: nel caso di 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 Vediamo ora un altro tipo di ciclo, più semplice nella sua costruzione: 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. Anche in questa situazione, comunque, il concetto fondamentale è che l'esecuzione del ciclo termina quando la condizione fra parentesi non è più verificata: ancora una volta, quindi, è possibile che il ciclo non sia eseguito mai, nel caso in cui la condizione risulti falsa fin da subito. Il ciclo do...while 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 Abbiamo visto che 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: infatti 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; } echo "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.



Ciclo Foreach Esiste un ultimo tipo di ciclo, ed è un ciclo particolare perchè è costruito appositamente per il trattamento degli array e di particolari oggetti chiamati Iteratori: si tratta del foreach. Questo ci permette di costruire un ciclo che viene ripetuto per ogni elemento di una collezione passata come argomento. La sintassi è la seguente: foreach ($arr as $chiave => $valore) { <codice> } 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. È 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) { <codice> }


Array: Regole sintattiche

Gli array, o vettori, sono collezioni monodimensionali o multidimensionali di oggetti di natura eterogenea associati a indici di accesso. Un oggetto appartenente a un array può essere un numero, una stringa, un oggetto complesso oppure un altro array.

Gli array rivestono un ruolo fondamentale in PHP, al punto che il linguaggio fornisce un numero elevatissimo di funzioni native dedicate proprio alla gestione di questi potentissimi oggetti.

In questo capitolo analizzeremo come si possono utilizzare con profitto gli array negli script PHP.

La dichiarazione di un array avviene all’interno di uno script PHP esattamente come avviene la dichiarazione di una variabile, a eccezione del fatto che un array è dotato di una coppia di parentesi quadre che fanno capire al motore PHP che l’oggetto che si sta dichiarando è, appunto, un array e non una semplice variabile.

Per dichiarare un array si può utilizzare una delle seguenti sintassi:

// istanzia un array inizialmente vuoto
$rubricatelefonica[];

// istanzia un array contenente un elemento di tipo
// stringa
// per referenziare l'elemento sarà necessario
// utilizzare la chiave 0
$rubricatelefonica[0]="Paperino";

// istanzia un array contenente un elemento di tipo
// stringa
// per referenziare l'elemento sarà necessario
// utilizzare
// una chiave al momento sconosciuta
$rubricatelefonica[]="Paperino";

// istanzia un array contenente un elemento di tipo stringa
// per referenziare l'elemento sarà necessario utilizzare la chiave "direttore"
$rubricatelefonica["direttore"]="Paperino";



Esempio del tipo di dato array

$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:

echo $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". Come abbiamo detto, questa sintassi è valida anche per definire un array, in alternativa a quella usata prima: infatti, se ipotizziamo che l'array $colori non fosse ancora definito, questa istruzione lo avrebbe definito creando l'elemento con indice 0. È naturalmente possibile anche indicare direttamente l'indice, anche in modo non consecutivo:

$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'. È 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'. È da ricordare che le chiavi numeriche ed associative possono coesistere nello stesso array. Vediamo un esempio, 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.



Array monodimensionali: Dichiarazione

Un array monodimensionale è una semplice lista che associa un certo numero di valori a chiavi di accesso appropriate.

Normalmente le chiavi sono di tipo numerico, ma è possibile anche avere anche array dotati di chiavi alfanumeriche.

Vediamo un esempio di utilizzo degli array:

<html>
<head>
<title>Array monodimensionale</title>
</head>
<body>
<table border="1">
<?php
$vocali = array ("A", "E", "I", "O", "U");
print("<tr><td colspan=\"" . count($vocali) . "\">");
print("<b>Le vocali sono: </b> ");
print("</td></tr>");
print("<tr>");
foreach ($vocali as $k => $v)
{
print("<td>$v ($k)</td>");
}
print("</tr>");
?>
</table>
</body>
</html>

Questo esempio, mostra come è possibile creare un array già inizializzato con una serie di valori, cioè attraverso l’istruzione:

$vocali = array ("A", "E", "I", "O", "U");

Questo è il metodo più immediato per costruire un array già inizializzato che può essere poi scandito, come abbiamo già visto in precedenza, attraverso il comodo costrutto foreach.

Questo metodo di costruzione di un’array assegna automaticamente a ogni elemento dell’array una chiave numerica a partire dalla chiave zero. Il valore della chiave, infatti, viene stampato dallo script di esempio racchiuso tra parentesi a fianco a ogni singolo valore.

Nello script dell’esempio è stata anche utilizzata una funzione nativa di PHP, la funzione count, che serve a calcolare il numero di elementi di un array: questa informazione ci è servita per costruire correttamente la cella della tabella attraverso l’attributo HTML colspan.



Aggiunta di elementi e navigazione

Una volta dichiarato un array è ovviamente possibile aggiungere degli elementi e leggerne il contenuto. Vediamo un esempio:

<html>
<head>
<title>Uso degli Array</title>
</head>
<body>
<?php
$citta = array ("Torino", "Milano", "Roma");
$citta[] = "Napoli" ;
$citta[] = "Palermo" ;
$citta[] = "Cagliari" ;

print("<table border=\"1\">");
print("<tr><td>Elenco città</td></tr>");
for ($i=0;$i<count($citta);$i++)
{
print("<tr><td>$citta[$i]</td></tr>");
}
print("</table>");
?>
</body>
</html>

Il risultato dell’esecuzione di questo script, una volta definito un array secondo la modalità esaminata in precedenza è possibile aggiungere elementi utilizzando la sintassi:

$nome_array[] = valore_da_aggiungere ;

Quando invece è necessario leggere le informazioni presenti in un array per memorizzarle in una variabile si può utilizzare la sintassi:

$variabile = nome_array[valore_chiave] ;

Il valore delle chiavi non deve essere necessariamente numerico: è possibile infatti dichiarare e utilizzare array che associano valori a chiavi personalizzate. Vediamo un esempio:

<html>
<head>
<title>Chiavi personalizzate</title>
</head>
<body>
<?php
$ruolo["Amministratore"] = "Carlo" ;
$ruolo["Direttore Generale"] = "Ernesto" ;
$ruolo["Capo dipartimento"] = "Piero" ;

foreach ($ruolo as $k => $v)
{
print("Ruolo: $k - Nome: $v<br>");
}
?>
</body>
</html>

Nel codice dell’esempio è stato creato l’array $ruolo associando a delle chiavi personalizzate (il ruolo in azienda) il nome di chi ricopre quel ruolo.

La sintassi generica per aggiungere a un array un elemento dotato di una chiave personalizzata è la seguente:

$nome_array[nome_chiave] = valore ;

e per accedervi si utilizza la solita sintassi vista in precedenza.

Questa funzionalità è molto interessante.

L’utilizzo di chiavi personalizzate preclude la possibilità di navigare all’interno di un array attraverso gli strumenti automatici basati sugli indici numerici.

Un frammento di codice di questo tipo, per esempio:

for ($i=0;$i<count($ruolo);$i++)
{
print("$ruolo[$i]");
}

non sarebbe applicabile in quanto il ciclo for basa il suo funzionamento sull’indicizzazione numerica delle chiavi.

Per questo motivo, nei casi di utilizzo di chiavi alfanumeriche è preferibile servirsi degli strumenti dedicati espressamente alla navigazione all’interno degli array, come il costrutto foreach.



Altri metodi di inizializzazione

Finora abbiamo visto come inizializzare un array assegnando automaticamente dei valori agli elementi e successivamente come associare chiavi personalizzate a valori inseriti nell’array.

Queste due operazioni possono essere eseguite contemporaneamente. Vediamo un esempio:

<html>
<head>
<title>Inizializzazione di array</title>
</head>
<body>
<?php
$persona = array(
"Nome" => "Carlo",
"Cognome" => "Giacomini",
"Indirizzo" => "Via Roma 1",
"Citta" => "Torino",
"Cap" => "10100") ;

print("<b>Scheda personale</b><br>");
foreach ($persona as $k => $v)
{
print("$k: $v<br>");
}
?>
</body>
</html>

Con questo script è stata realizzata una scheda personale le cui informazioni sono contenute all’interno di un array.

A ogni tipologia di informazione, rappresentata da una chiave personalizzata, è stato associato il valore corretto direttamente in fase di inizializzazione.

Anche in questo caso per accedere alle informazioni si utilizza un ciclo foreach che consente la navigazione completa tra tutti gli elementi dell’array.



Array multidimensionali

All’inizio del capitolo si è detto che gli array sono collezioni di oggetti che possono contenere, tra le varie tipologie di informazioni, anche altri array.

La possibilità di avere un array che ne contiene altri consente di creare strutture multidimensionali complesse come matrici, strutture spaziali o dotate addirittura di un numero superiore di dimensioni.

Vediamo un esempio in cui si cerca di ricostruire la struttura di una scacchiera per il gioco degli scacchi:

<?php
function getBgColor()
{
static $col = "black";
$col=($col=="black"?"white":"black");
return $col;
}

function getColor()
{
static $index = 1;
if ($index <= 16) {$col="red";}
else {$col="green";}
$index++;
return $col;
}
?>

<html>
<head>
<title>Scacchiera</title>
</head>
<body>
<?php
$scacchiera[] = array("T","C","A","Q","K","A","C","T");
$scacchiera[] = array("P","P","P","P","P","P","P","P");
$scacchiera[] = array(" "," "," "," "," "," "," "," ");
$scacchiera[] = array(" "," "," "," "," "," "," "," ");
$scacchiera[] = array(" "," "," "," "," "," "," "," ");
$scacchiera[] = array(" "," "," "," "," "," "," "," ");
$scacchiera[] = array(" "," "," "," "," "," "," "," ");
$scacchiera[] = array("P","P","P","P","P","P","P","P");
$scacchiera[] = array("T","C","A","K","Q","A","C","T");

print("<table border=\"1\">");
for ($i=0;$i<count($scacchiera);$i++)
{
print("<tr>");
for ($j=0;$j<count($scacchiera[$i]);$j++)
{
print("<td bgcolor=\"" . getBgColor() . "\"><font color=\"" . getColor() . "\">" .
($scacchiera[$i][$j]==" "?"&nbsp;":$scacchiera[$i][$j]) .
"</font></td>");
}
print("</tr>");
getBgColor();
}
print("</table>");

?>
</body>
</html>

Questo esempio, rappresenta uno script sufficientemente completo che tocca molti degli argomenti trattati fino a ora.

Innanzitutto si noti che il corpo principale dello script comincia definendo il nuovo array $scacchiera, ma, contrariamente agli esempi precedenti, i singoli elementi non sono semplici variabili, ma sono anch’essi array.

In particolare l’istruzione:

$scacchiera[] = array("T","C","A","Q","K","A","C","T");

aggiunge un elemento all’array $scacchiera e l’elemento che viene aggiunto è a sua volta un array che rappresenta una riga della nostra scacchiera virtuale. Gli otto elementi contenuti sono stringhe che identificano la presenza, in ogni posizione di quella riga, dell’elemento appropriato del gioco degli scacchi: torre, cavallo, alfiere, regina e re.

La riga successiva inserisce, nella seconda riga della scacchiera, una riga di pedoni, mentre lo spazio rappresenta l’assenza di pezzi in una determinata posizione.

Al termine della costruzione dell’array multidimensionale $scacchiera abbiamo una rappresentazione virtuale completa di una scacchiera preparata per il gioco degli scacchi e possiamo leggerla per stamparla all’interno di una pagina HTML.

Per raggiungere questo obiettivo si stampa l’apertura di una tabella attraverso l’istruzione:

print("<table border=\"1\">");

e successivamente si effettuano due cicli, l’uno annidato nell’altro. Il primo scandisce tutti gli elementi riga ed è ottenuto attraverso il blocco di istruzioni:

for ($i=0;$i<count($scacchiera);$i++)
{
// scansione di tutte le righe
}

Questo ciclo provvede anche a stampare ogni singola riga attraverso la produzione in output dei tag HTML di apertura e chiusura della riga stessa all’interno della tabella.

Il secondo ciclo, quello più interno, che scandisce ogni singolo elemento della riga selezionata e provvede a stamparlo viene realizzato attraverso il ciclo:

for ($j=0;$j<count($scacchiera[$i]);$j++)
{
// scansione di tutti gli elementi della riga
}

Per ottenere l’effetto di alternanza tra lo sfondo bianco e quello nero all’interno della scacchiera, si utilizza la funzione getBgColor che, attraverso l’utilizzo di una variabile statica, restituisce a ogni chiamata un valore diverso tra i colori bianco e nero.

Nel caso della scacchiera iniziale per il gioco degli scacchi è necessario anche individuare il colore di ogni singolo pezzo.

Questo viene realizzato attraverso l’utilizzo della funzione getColor che restituisce il colore rosso per i primi sedici elementi, cioè per le prime due righe, e successivamente restituisce il colore verde.

Naturalmente questa metodologia di stampa ha significato esclusivamente quando si cerca di rendere in output una scacchiera il cui stato interno sia quello iniziale. Un tentativo di stampa di una scacchiera in uno stato diverso produrrebbe un risultato non corretto, soprattutto per l’algoritmo utilizzato per la definizione del colore di ogni singolo pezzo sulla scacchiera.

Quando ci troviamo nel ciclo più interno stiamo analizzando l’elemento le cui coordinate (che vanno da zero a n-1) sono indirizzate direttamente dalle variabili $i e $j.

Come si vede dall’esempio, è possibile ottenere il valore dell’elemento indirizzabile a queste coordinate attraverso la sintassi:

$scacchiera[$i][$j]

Nel caso specifico della stampa del valore presente in quelle coordinate, poiché l’esigenza funzionale è di stamparlo all’interno di una cella di una tabella HTML, è importante testare il valore presente in quella posizione perché se si tratta di un semplice spazio questo dovrà essere convertito in una carattere speciale HTML identificato attraverso la entità &nbsp; in caso contrario, la stampa non sarà come ce l’aspettiamo in quanto il browser, in alcuni contesti, ignora gli spazi.

Per stampare il valore presente in un certo gruppo di coordinate dell’array sono stati usati alcuni operatori di concatenazione attraverso la sintassi:

print("stringa1 " . $scacchiera[$i][$j] . " stringa2");

Questo è uno dei modi per referenziare un elemento di un array all’interno di una stringa.

Esiste però una sintassi alternativa che è la seguente:

print("stringa1 {$scacchiera[$i][$j]} stringa2");

Ogni elemento dell’array, in questo caso, può essere inserito direttamente all’intero della stringa dove vogliamo che sia stampato, esattamente come avviene per le variabili tradizionali, a condizione però che sia racchiuso tra parentesi graffe.



Rappresentazione spaziale

Un array multidimensionale può essere, come abbiamo visto, una matrice rappresentabile graficamente.

La potenza della multidimensionalità consente anche la realizzazione di oggetti ben più complessi e non rappresentabili sul piano dell’interfaccia Web, si pensi per esempio a una rappresentazione spaziale tridimensionale come un cubo.

Ecco un esempio di come sia semplice ottenere un oggetto del genere:

<html>
<head>
<title>Cubo</title>
</head>
<body>
<?php
for($x=1;$x<=10;$x++)
{
for($y=1;$y<=10;$y++)
{
for($z=1;$z<=10;$z++)
{
$cubo[$x][$y][$z] = rand(1,100);
}
}
}

for($x=1;$x<=10;$x++)
{
for($y=1;$y<=10;$y++)
{
for($z=1;$z<=10;$z++)
{
print("\$cubo[$x][$y][$z]={$cubo[$x][$y][$z]}<br>");
}
}
}
?>
</body>
</html>

Non è stata possibile una rappresentazione grafica piana in quanto la sua costruzione tridimensionale la impedisce.

In ogni caso, da questo script si può vedere come sia semplice aggiungere un elemento al cubo: è sufficiente indicare le coordinate in cui questo elemento debba essere inserito attraverso una sintassi simile a questa:

$cubo[$x][$y][$z] = valore;

Allo stesso modo per leggere il valore è sufficiente indicarne le coordinate in questo modo:

print("\$cubo[$x][$y][$z]={$cubo[$x][$y][$z]}<br>");

La potenza di questi oggetti ci permette di creare strutture dati anche complesse in maniera piuttosto semplice e di utilizzarle per memorizzarvi le informazioni più disparate.

Anche il recupero di queste informazioni, come abbiamo visto, non presenta problemi particolari.



Operatore +

Abbiamo visto in altri esempi che l’operatore + può essere usato come strumento per sommare due elementi di tipo numerico oppure per concatenare due stringhe.

Se questo operatore viene usato con gli array il suo comportamento cambia radicalmente. Vediamo un esempio:

<html>
<head>
<title>Operatore + con gli array</title>
</head>
<body>
<?php
$rubrica = array("1234" => "Rag. Rossi",
"1235" => "Dott. Bianchi",
"1237" => "Ing. Verdi");
$aggiornamento = array("1236" => "Rag. Giallo",
"1237" => "Dott. Fucsia",
"1238" => "Cav. Neri");

print("<b>Rubrica iniziale</b><br>");
foreach ($rubrica as $k => $v)
{
print("$v: $k<br>");
}

print("<b>Aggiornamento</b><br>");
foreach ($aggiornamento as $k => $v)
{
print("$v: $k<br>");
}

print("<b>Rubrica Finale</b><br>");
foreach ($rubrica + $aggiornamento as $k => $v)
{
print("$v: $k<br>");
}

?>
</body>
</html>

In questo script abbiamo costruito due diversi array, uno per definire una rubrica aziendale alla sua versione iniziale, l’altro per definire un possibile aggiornamento dei dati della rubrica.

Dall’output dell’esempio, si vede chiaramente che il comportamento dell’operatore + associato a elementi di tipi array consente di effettuare vere operazioni di unione geometrica tra gli insiemi.

Quando si utilizza l’operatore “pi “ come nell’esempio: $rubrica + $aggiornamento si ottiene un array composto dall’unione di tutti gli elementi del primo e del secondo array.

Gli elementi presenti in un array ma non nell’altro vengono semplicemente aggiunti.

Nel caso, invece, di sovrapposizione di chiavi, dove cioè nei due array esistono elementi diversi associati a una chiave, gli elementi del secondo array, cioè quello alla destra dell’operatore +, vengono ritenuti più importanti e pertanto sostituiranno nell’altro array gli elementi dotati di identica chiave.