• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Info PHP di Base Lez #3 Gli array

Matta

Utente Attivo
Autore del topic
6 Maggio 2010
410
0
Miglior risposta
0
Precedentemente abbiamo accennato il tipo di dato array con il seguente esempio:

$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 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 => 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.

È da notare che quando abbiamo usato le chiavi associative le abbiamo indicate fra apici: ciò è necessario per mantenere la 'pulizia' del codice, in quanto, se non usassimo gli apici (come spesso si vede fare), PHP genererebbe un errore di tipo 'notice', anche se lo script funzionerebbe ugualmente (dato che il valore verrebbe convertito automaticamente in una stringa). Vediamo ora qualche esempio di creazione e stampa dei valori di un array:

$persona['nome'] = 'Mario'; //corretto
$persona[cognome] = 'Rossi'; /*funziona, ma genera un errore 'notice'*/
echo $persona['cognome']; //stampa 'Rossi': corretto
echo "ciao $persona[nome]"; /*stampa 'ciao Mario': corretto (niente apici fra virgolette)*/
echo "ciao $persona['nome']"; //NON FUNZIONA, GENERA ERRORE
echo "ciao {$persona['nome']}"; /*corretto: per usare gli apici fra virgolette dobbiamo comprendere il tutto fra parentesi graffe*/
echo "ciao " . $persona['nome']; /*corretto: come alternativa, usiamo il punto per concatenare (v. lez.10 sugli operatori)*/
Abbiamo così visto in quale maniera possiamo creare ed assegnare valori agli array, usando indici numerici o associativi, impostando esplicitamente le chiavi o lasciando che sia PHP ad occuparsene. 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'.

Le funzioni in PHP:gestire le variabili

Anche se la versione 5 ha portato un grosso supporto per la programmazione ad oggetti (che tratteremo brevemente anche nei paragrafi successivi) le funzioni rimangono comunque la parte fondamentale del linguaggio dato che PHP è nato come linguaggio procedurale, e tutt'oggi molti sviluppatori continuano a seguire questa filosofia di programmazione.

Una funzione è un insieme di istruzioni che hanno lo scopo (la funzione, appunto) di eseguire determinate operazioni. La praticità delle funzioni sta nel fatto che ci consentono di non dover riscrivere tutto il codice ogni volta che abbiamo la necessità di eseguire quelle operazioni comuni: ci basta infatti richiamare l'apposita funzione, fornendole i parametri, cioè i dati/informazioni, di cui ha bisogno per la sua esecuzione.

Le funzioni possono essere incorporate nel linguaggio oppure essere definite dall'utente. In entrambi i casi, il modo di richiamarle è lo stesso.

La sintassi fondamentale con la quale si richiama una funzione è molto semplice:

nome_funzione();
Si tratta semplicemente di indicare il nome della funzione, seguito da parentesi tonde. Queste parentesi devono contenere i parametri da passare alla funzione, ma vanno obbligatoriamente indicate anche se non ci sono parametri, nel qual caso rimangono vuote come nell'esempio che abbiamo visto sopra. Nel caso poi in cui la funzione restituisca un valore, possiamo indicare la variabile in cui immagazzinarlo:

$valore = nome_funzione();
In questo modo, la variabile $valore riceverà il risultato della funzione. Le funzioni possono essere utilizzate anche all'interno di espressioni: in tal caso il valore restituito verrà utilizzato durante la valutazione dell'espressione:

$prova = (10 * numero_anni()) - numero_casuale();
Abbiamo detto che le funzioni possono essere incorporate nel linguaggio oppure definite dall'utente: in questa lezione passeremo in rassegna alcune fra le funzioni incorporate maggiormente utilizzate in PHP, tenendo però presente che tali funzioni sono numerosissime, rivolte agli scopi più disparati, e che quindi non ne avremo che una visione molto parziale. Consiglio la consultazione del manuale online per una trattazione più completa delle funzionalità e dei casi particolari.

Cominciamo dalle principali funzioni che operano sulle variabili in generale:

empty(valore)
verifica se la variabile che le passiamo è vuota oppure no. Per 'vuota' si intende che la variabile può contenere una stringa vuota o un valore numerico pari a 0, ma può anche essere non definita o essere impostata al valore NULL (l'eventuale indicazione di una variabile non definita, in questo caso, non genera errore notice). Restituisce un valore booleano (vero o falso).
isset(valore)
verifica se la variabile è definita. Una variabile risulta non definita quando non è stata inizializzata o è stata impostata col valore NULL. Restituisce un valore booleano.
is_null(valore)
verifica se la variabile equivale a NULL, ma genera un errore 'notice' se viene eseguito su una variabile non definita. Restituisce un valore booleano.
is_int(valore), is_integer(valore), is_long(valore)
verifica se la variabile è di tipo intero. Le tre funzioni sono equivalenti. Restituiscono un valore booleano.
is_float(valore), is_double(valore), is_real(valore)
verifica se la variabile è di tipo numerico double (o float). Le tre funzioni sono equivalenti. Restituiscono un valore booleano.
is_string(valore)
verifica se la variabile è una stringa. Restituisce un valore booleano.
is_array(valore)
verifica se la variabile è un array. Restituisce un valore booleano.
is_numeric(valore)
verifica se la variabile contiene un valore numerico. È molto importante la distinzione fra questa funzione e is_int() o is_float(), perchè queste ultime, nel caso di una stringa che contiene valori numerici, restituiscono falso, mentre is_numeric() restituisce vero. Restituisce un valore booleano.
gettype(valore)
verifica quale tipo di dato le abbiamo passato. Restituisce una stringa che rappresenta il tipo di dato, ad esempio: boolean, integer, double, string, array. È bene però, in uno script, non fare affidamento su questi valori per dedurre il tipo di dato, perchè in versioni future di PHP alcune di queste stringhe potrebbero essere modificate. Meglio usare le funzioni viste prima.
print_r(valore)
stampa (direttamente sul browser) informazioni relative al contenuto della variabile che le abbiamo passato. È utile in fase di debug, quando a seguito di comportamenti 'strani' del nostro script vogliamo verificare il contenuto di certi dati. Se il valore passato è un array, la funzione ne evidenzia le chiavi ed i valori relativi. Restituisce un valore booleano.
unset(valore)
distrugge la variabile specificata. In realtà non si tratta di una funzione, ma di un costrutto del linguaggio, e ne abbiamo già parlato nella lez. 8. Dopo l'unset(), l'esecuzione di empty() o is_null() sulla stessa variabile restituirà vero, mentre isset() restituirà falso. Non restituisce valori.
Vediamo ora qualche esempio per chiarire l'utilizzo di queste funzioni:

$b = empty($a); // $a non è ancora definita, quindi $b sarà vero
$a = 5;
$b = isset($a); // vero
$b = is_float($a); // falso: $a è un intero
$b = is_string($a); // falso

$a = '5';
$b = is_int($a); // falso: $a ora è una stringa
$b = is_string($a); // vero
$b = is_numeric($a); // vero: la stringa ha un contenuto numerico
$c = gettype($b); // $c prende il valore 'boolean'

unset($a); // eliminiamo la variabile $a;
$b = is_null($a); // vero, ma genera errore
In questi esempi abbiamo sempre assegnato alla variabile $b i valori booleani restituiti dalle funzioni. Nella pratica, è più frequente che tali valori non siano memorizzati in variabili, ma che vengano usati direttamente come condizioni, ad esempio per delle istruzioni di tipo if. Ancora un paio di esempi:

if (empty($a)) {
print ('$a è vuota o non definita!');
} else {
print ('$a contiene un valore');
}

if (is_numeric($a)){
print ('$a contiene un valore numerico');
} else {
print ('$a non contiene un numero');
}

Le funzioni in PHP:gestire le stringhe

Passiamo ora ad esaminare alcune funzioni che operano sulle stringhe (l'eventuale indicazione di un parametro tra parentesi quadre indica che quel parametro è facoltativo, quindi può non essere indicato nel momento in cui si chiama la funzione):

strlen(stringa)
verifica la lunghezza della stringa, cioè il numero di caratteri che la compongono. Restituisce un numero intero.
trim(stringa)
elimina gli spazi all'inizio e alla fine della stringa. Restituisce la stringa modificata.
ltrim(stringa)
elimina gli spazi all'inizio della stringa. Restituisce la stringa modificata.
rtrim(stringa)
elimina gli spazi alla fine della stringa. Restituisce la stringa modificata.
substr(stringa, intero [, intero])
restituisce una porzione della stringa, in base al secondo parametro (che indica l'inizio della porzione da estrarre), e all'eventuale terzo parametro, che indica quanti caratteri devono essere estratti. Se il terzo parametro non viene indicato, viene restituita tutta la parte finale della stringa a partire dal carattere indicato.

I caratteri vanno contati a partire da zero, per cui se si chiama la funzione con substr(stringa, 4) verranno restituiti tutti i caratteri a partire dal quinto. Si può anche indicare un numero negativo come carattere iniziale: in questo caso, il carattere iniziale della porzione di stringa restituita verrà contato a partire dal fondo.

Ad esempio, con substr(stringa, -5, 3) si otterranno tre caratteri a partire dal quintultimo (da notare che in questo caso il conteggio non inizia da zero, ma da 1: cioè -1 indica l'ultimo carattere, -2 il penultimo e così via).

Se infine si indica un numero negativo come terzo parametro, tale parametro non verrà più utilizzato come numero di caratteri restituiti, ma come numero di caratteri non restituiti a partire dal fondo. Esempio: substr(stringa, 3, -2) restituisce i caratteri dal quarto al terzultimo. La funzione restituisce la porzione di stringa richiesta.
str_replace(stringa, stringa, stringa)
effettua una sostituzione della prima stringa con la seconda all'interno della terza. Ad esempio: str_replace('p', 't', 'pippo') sostituisce le 'p' con le 't' all'interno di 'pippo', e quindi restituisce 'titto'. Restituisce la terza stringa modificata. Esiste anche la funzione str_ireplace(), che è equivalente ma che cerca la prima stringa nella terza senza tener conto della differenza fra maiuscole e minuscole.
strpos(stringa, stringa)
cerca la posizione della seconda stringa all'interno della prima. Ad esempio: strpos('Lorenzo', 're') restituisce 2, ad indicare la terza posizione. Restituisce un intero che rappresenta la posizione a partire da 0 della stringa cercata. Se la seconda stringa non è presente nella prima, restituisce il valore booleano FALSE. La funzione stripos() fa la stessa ricerca senza tenere conto della differenza fra maiuscole e minuscole.
strstr(stringa, stringa)
cerca la seconda stringa all'interno della prima, e restituisce la prima stringa a partire dal punto in cui ha trovato la seconda. strstr('Lorenzo', 're') restituisce 'renzo'. Restituisce una stringa se la ricerca va a buon fine, altrimenti il valore booleano FALSE. La funzione stristr() funziona allo stesso modo ma non tiene conto della differenza fra maiuscole e minuscole.
strtolower(stringa)
converte tutti i caratteri alfabetici nelle corrispondenti lettere minuscole. Restituisce la stringa modificata.
strtoupper(stringa)
converte tutti i caratteri alfabetici nelle corrispondenti lettere maiuscole. Restituisce la stringa modificata.
ucfirst(stringa)
trasforma in maiuscolo il primo carattere della stringa. Restituisce la stringa modificata.
ucwords(stringa)
trasforma in maiuscolo il primo carattere di ogni parola della stringa, intendendo come parola una serie di caratteri che segue uno spazio. Restituisce la stringa modificata.
explode(stringa, stringa [, intero])
trasforma la seconda stringa in un array, usando la prima per separare gli elementi. Il terzo parametro può servire ad indicare il numero massimo di elementi che l'array può contenere (se la suddivisione della stringa portasse ad un numero maggiore, la parte finale della stringa sarà interamente contenuta nell'ultimo elemento).

Ad esempio: explode(' ', 'ciao Mario') restituisce un array di due elementi in cui il primo è 'ciao' e il secondo 'Mario'. Restituisce un array.
Dobbiamo fare un'annotazione relativa a tutte queste funzioni, in particolare quelle che hanno lo scopo di modificare una stringa: la stringa modificata è il risultato della funzione, che dovremo assegnare ad una variabile apposita. Le variabili originariamente passate alla funzione rimangono invariate. Vediamo alcuni esempi sull'uso di queste funzioni:

$a = 'IERI ERA DOMENICA';

/* $b diventa 'ieri era domenica',
* ma $a rimane 'IERI ERA DOMENICA'
*/
$b = strtolower($a);

strlen('abcd'); // restituisce 4
trim(' Buongiorno a tutti '); // restituisce 'Buongiorno a tutti'
substr('Buongiorno a tutti', 4); // 'giorno a tutti' (inizia dal quinto)
substr('Buongiorno a tutti', 4, 6); // 'giorno'(6 caratteri a partire dal quinto)
substr('Buongiorno a tutti', -4); // 'utti' (ultimi quattro)
substr('Buongiorno a tutti', -4, 2); // 'ut' (2 caratteri a partire dal quartultimo)
substr('Buongiorno a tutti, 4, -2); // 'giorno a tut' (dal quinto al terzultimo)


str_replace('Buongiorno', 'Ciao', 'Buongiorno a tutti'); // 'Ciao a tutti'
str_replace('dom', 'x', 'Domani è domenica'); // 'Domani è xenica'
str_ireplace('dom', 'x', 'Domani è domenica'); // 'xani è xenica'

strpos('Domani è domenica', 'm'); // 2 (prima 'm' trovata)
strstr('Domani è domenica', 'm'); // 'mani è domenica' (a partire dalla prima 'm')

strtoupper('Buongiorno a tutti'); // 'BUONGIORNO A TUTTI'
ucfirst('buongiorno a tutti'); // 'Buongiorno a tutti';
ucwords('buongiorno a tutti'); // 'Buongiorno A Tutti';

/* suddivide la stringa in un array, separando un elemento
* ogni volta che trova una virgola; avremo quindi un array
* di tre elementi: ('Alberto','Mario','Giovanni')
*/
explode(',','Alberto,Mario,Giovanni');

/* in questo caso l'array può contenere al massimo due elementi,
* per cui nel primo elemento andrà 'Alberto' e nel secondo il
* resto della stringa: 'Mario,Giovanni'
*/
explode(',','Alberto,Mario,Giovanni',2);

Le funzioni in PHP:gestire gli array

Vediamo ora alcune funzioni che operano sugli array:

count(array)
conta il numero di elementi dell'array. Restituisce un intero.
array_reverse(array [, booleano])
inverte l'ordine degli elementi dell'array. Se vogliamo mantenere le chiavi dell'array di input, dobbiamo passare il secondo parametro con valore TRUE. Restituisce l'array di input con gli elementi invertiti.
sort(array)
ordina gli elementi dell'array. Bisogna fare attenzione, perchè questa funzione, contrariamente a molte altre, modifica direttamente l'array che le viene passato in input, che quindi andrà perso nella sua composizione originale. I valori vengono disposti in ordine crescente secondo i criteri che abbiamo visto nella lezione 10. Le chiavi vanno perse: dopo il sort, l'array avrà chiavi numeriche a partire da 0 secondo il nuovo ordinamento. Non restituisce nulla.
rsort(array)
ordina gli elementi dell'array in ordine decrescente. Anche questa funzione modifica direttamente l'array passato in input e riassegna le chiavi numeriche a partire da 0. Non restituisce nulla.
asort(array)
funziona come sort(), con la differenza che vengono mantenute le chiavi originarie degli elementi. Non restituisce nulla.
arsort(array)
come rsort(), ordina in modo decrescente; mantiene però le chiavi originarie. Non restituisce nulla.
in_array(valore, array)
cerca il valore all'interno dell'array. Restituisce un valore booleano: vero o falso a seconda che il valore cercato sia presente o meno nell'array.
array_key_exists(valore, array)
cerca il valore fra le chiavi (e non fra i valori) dell'array. Restituisce un valore booleano.
array_search(valore, array)
cerca il valore nell'array e ne indica la chiave. Restituisce la chiave del valore trovato o, se la ricerca non va a buon fine, il valore FALSE.
array_merge(array, array [, array...])
fonde gli elementi di due o più array. Gli elementi con chiavi numeriche vengono accodati l'uno all'altro e le chiavi rinumerate. Le chiavi associative invece vengono mantenute, e nel caso vi siano più elementi nei diversi array con le stesse chiavi associative, l'ultimo sovrascrive i precedenti. Restituisce l'array risultante dalla fusione.
array_pop(array)
estrae l'ultimo elemento dell'array, che viene 'accorciato'. Restituisce l'elemento in fondo all'array e, contemporaneamente, modifica l'array in input togliendogli lo stesso elemento.
array_push(array, valore [,valore...])
accoda i valori indicati all'array. Equivale all'uso dell'istruzione di accodamento $array[]=$valore , con il vantaggio che ci permette di accodare più valori tutti in una volta. Restituisce il numero degli elementi dell'array dopo l'accodamento.
array_shift(array)
estrae un elemento come array_pop(), ma in questo caso si tratta del primo. Anche in questo caso l'array viene 'accorciato', ed inoltre gli indici numerici vengono rinumerati. Rimangono invece invariati quelli associativi. Restituisce l'elemento estratto dall'array.
array_unshift(array, valore [,valore...])
inserisce i valori indicati in testa all'array. Restituisce il numero degli elementi dell'array dopo l'inserimento.
implode(stringa, array)
è la funzione opposta di explode(), e serve a riunire in un'unica stringa i valori dell'array. La stringa indicata come primo parametro viene interposta fra tutti gli elementi dell'array. Restituisce la stringa risultato dell'aggregazione. Suo sinonimo è join().
Ecco qualche esempio sull'uso di queste funzioni:

$arr = array('Luca', 'Giovanni', 'Matteo', 'Paolo', 'Antonio', 'Marco', 'Giuseppe');

$n = count($arr); // $n vale 7
$arr1 = array_reverse($arr); // $arr1 avrà gli elementi invertiti, da 'Giuseppe' a 'Luca'
echo $arr[1], '<br>'; // 'Giovanni'
echo $arr1[1], '<br>'; // 'Marco'

/* ora $arr sarà:
* 'Antonio', 'Giovanni', 'Giuseppe', 'Luca', 'Marco', ' Matteo', 'Paolo'
*/
sort($arr);

$a = in_array('Giovanni', $arr); // $a è vero (TRUE)
$a = in_array('Francesco', $arr); // $a è falso (FALSE)
$ultimo = array_pop($arr); // $ultimo è 'Paolo' (li avevamo ordinati!)
$ultimo = array_pop($arr); // ora $ultimo è 'Matteo', e in $arr sono rimasti 5 elementi
$primo = array_shift($arr); // primo è 'Antonio'

/* 'Matteo' e 'Antonio' vengono reinseriti in testa all'array;
* $a riceve il valore 6
*/
$a = array_unshift($arr, $ultimo, $primo);

$stringa = implode(' ', $arr); // $stringa diventa 'Matteo Antonio Giovanni Giuseppe Luca Marco' */

/* $new_arr conterrà 13 elementi:
* 'Matteo', 'Antonio', 'Giovanni',
* 'Giuseppe', 'Luca', 'Marco' (questi sono i 6 provenienti da $arr),
* 'Giuseppe', 'Marco',' Antonio', 'Paolo',
* 'Matteo', 'Giovanni', 'Luca' (questi sono i 7 di $arr1). Gli indici andranno da 0 a 12.
*/
$new_arr = array_merge($arr, $arr1);

// Impostiamo ora un array con chiavi associative:
$famiglia = array('padre' => 'Claudio', 'madre' => 'Paola', 'figlio' => 'Marco', 'figlia' => 'Elisa');
// creiamo una copia del nostro array per poter fare esperimenti
$fam1 = $famiglia;
// ora $fam1 sarà 'Paola', 'Marco', 'Elisa', 'Claudio', con chiavi da 0 a 3
rsort($fam1);

$fam1 = $famiglia; // ripristiniamo l'array originale

/* di nuovo $fam1 sarà 'Paola', 'Marco', 'Elisa', 'Claudio',
* ma ciascuno con la sua chiave originale
* ('madre', 'figlio', 'figlia', 'padre')
*/
arsort($fam1);

$a = array_key_exists('figlia', $fam1); // $a è TRUE
$a = array_key_exists('zio', $fam1); // $a è FALSE
$a = array_search('Claudio', $fam1); // $a è 'padre'
$a = array_search('Matteo', $fam1); // $a è FALSE

Le funzioni in PHP:gestire le date

Concludiamo questa panoramica sulle funzioni di PHP con qualche funzione sulla gestione di date e ore. Prima di cominciare, però, dobbiamo fare un accenno al timestamp, sul quale si basano queste funzioni. Il timestamp è un numero intero, in uso da tempo sui sistemi di tipo UNIX, che rappresenta il numero di secondi trascorsi a partire dal 1° gennaio 1970. Ad esempio, il timestamp relativo alle 15.56.20 del 24 aprile 2003 è 1051192580.

Vediamo dunque queste funzioni e rimandiamo a questo articolo, in cui questa funzione viene analizzata approfonditamente:

time()
È la più semplice di tutte, perchè fornisce il timestamp relativo al momento in cui viene eseguita. Restituisce un intero (timestamp).
date(formato [,timestamp])
Considera il timestamp in input (se non è indicato, prende quello attuale) e fornisce una data formattata secondo le specifiche indicate nel primo parametro. Tali specifiche si basano su una tabella di cui riassumiamo i valori più usati:

Codice Descrizione
Y anno su 4 cifre
y anno su 2 cifre
n mese numerico (1-12)
m mese numerico su 2 cifre (01-12)
F mese testuale ('January' - 'December')
M mese testuale su 3 lettere ('Jan' - 'Dec')
d giorno del mese su due cifre (01-31)
j giorno del mese (1-31)
w giorno della settimana, numerico (0=dom, 6=sab)
l giorno della settimana, testuale ('Sunday' - 'Saturday' )
D giorno della settimana su 3 lettere ('Sun' - 'Sat')
H ora su due cifre (00-23)
G ora (0-23)
i minuti su due cifre (00-59)
s secondi su due cifre (00-59)

La funzione date() restituisce la stringa formattata che rappresenta la data.
mktime(ore, minuti, secondi, mese, giorno, anno)
È una funzione molto utile ma che va maneggiata con molta cura, perchè i parametri che richiede in input (tutti numeri interi) hanno un ordine abbastanza particolare, che può portare facilmente ad errori. Sulla base di questi parametri, mktime() calcola il timestamp, ma l'aspetto più interessante è che possiamo utilizzarla per fare calcoli sulle date. Infatti, se ad esempio nel parametro mese passiamo 14, PHP lo interpreterà come 12+2, cioè "febbraio dell'anno successivo", e quindi considererà il mese come febbraio ed aumenterà l'anno di 1. Ovviamente lo stesso tipo di calcoli si può fare su tutti gli altri parametri. Restituisce un intero (timestamp).
checkdate(mese, giorno, anno)
Verifica se i valori passati costituiscono una data valida. Restituisce un valore booleano.
Vediamo quindi qualche esempio anche per queste funzioni:

// $a riceve il timestamp del 24/4/2003 alle 15.56.20
$a = mktime(15,56,20,4,24,2003);
// $b sarà "24 Apr 03 - 15:56"
$b = date('d M y - H:i', $a);
// timestamp delle ore 14 di 60 giorni dopo il 24/4/2003
$a = mktime(14,0,0,4,24+60,2003);

$c = checkdate(5,1,2003); // vero
$c = checkdate(19,7,2003); // falso (19 non è un mese)
$c = checkdate(4,31,2003); // falso (31 aprile non esiste)

Scrivere funzioni personalizzate

Come abbiamo detto nella lezione precedente, oltre alle numerosissime funzioni incorporate in PHP abbiamo la possibilità di definire delle funzioni che ci permettono di svolgere determinati compiti in diverse parti del nostro script, o, meglio ancora, in script diversi, semplicemente richiamando la porzione di codice relativa, alla quale avremo attribuito un nome che identifichi la funzione stessa. Vediamo quindi ora come definire una funzione, fermo restando che, al momento di eseguirla, la chiamata si svolge con le stesse modalità con cui vengono chiamate le funzioni incorporate del linguaggio.

Immaginiamo, facendo il solito esempio banale, di voler costruire una funzione che, dati tre numeri, ci restituisca il maggiore dei tre. Vediamo il codice relativo:

function il_maggiore($num1, $num2, $num3)
{
if (! is_numeric($num1)) { return false; }
if (! is_numeric($num2)) { return false; }
if (! is_numeric($num3)) { return false; }

if ($num1 > $num2)
{
if ($num1 > $num3)
{
return $num1;
} else {
return $num3;
}
}
else
{
if ($num2 > $num3) {
return $num2;
} else {
return $num3;
}
}
}
Come vediamo, la definizione della funzione avviene attraverso la parola chiave function, seguita dal nome che abbiamo individuato per la funzione, e dalle parentesi che contengono i parametri (o argomenti) che devono essere passati alla funzione. Di seguito, contenuto fra parentesi graffe, ci sarà il codice che viene eseguito ogni volta che la funzione viene richiamata. Il nome della funzione deve essere necessariamente univoco, questo significa che non è possibile definire due funzioni aventi lo stesso nome.

All'interno della funzione vediamo l'istruzione return; questa istruzione è molto importante, perchè termina la funzione (cioè restituisce il controllo allo script nel punto in cui la funzione è stata chiamata) e contemporaneamente determina anche il valore restituito dalla funzione. Nel nostro esempio, i tre dati ricevuti in input vengono controllati, uno dopo l'altro, per verificare che siano numerici: in caso negativo (il test infatti viene fatto facendo precedere la funzione is_numeric() dal simbolo "!" di negazione), la funzione termina immediatamente, restituendo il valore booleano false.

Una volta verificato che i tre valori sono numerici, vengono posti a confronto i primi due, e poi quello dei due che risulta maggiore viene posto a confronto col terzo, per ottenere così il maggiore dei tre, che viene infine restituito come risultato della funzione. Quando sarà il momento di eseguire questa funzione potremo quindi usare questo codice:

$a = 9;
$b = 8;
$c = 15;
$m = il_maggiore($a, $b, $c); // $m diventa 15
Avete visto che abbiamo chiamato la funzione usando dei nomi di variabile diversi da quelli usati nella funzione stessa: la funzione infatti usa $num1, $num2, $num3, mentre lo script che la richiama utilizza $a, $b, $c. È molto importante ricordare che non c'è nessuna relazione definita tra i nomi degli argomenti che la funzione utilizza e quelli che vengono indicati nella chiamata. Ciò che determina la corrispondenza fra gli argomenti è, infatti, semplicemente la posizione in cui vengono indicati: nel nostro caso, quindi, $a diventerà $num1 all'interno della funzione, $b diventerà $num2 e $c diventerà $num3.

Avremmo potuto richiamare la nostra funzione anche passando direttamente i valori interessati, senza utilizzare le variabili:

$m = il_maggiore(9, 8, 15); // $m diventa 15

/* $m diventa FALSE, perchè il terzo argomento non è numerico e quindi
* i controlli all'inizio della funzione bloccano l'esecuzione
*/
$m = il_maggiore(9, 8, 'ciao');

Scope e argomenti facoltativi

Passiamo ora ad un altro argomento molto importante, che è l'ambito (scope) delle variabili. Infatti, le variabili utilizzate in una funzione esistono solo all'interno della funzione stessa, mentre non sono definite nè per le altre funzioni nè nello script principale. Allo stesso modo, le variabili usate dallo script principale non vengono viste dalle funzioni. Questa è una caratteristica molto importante del linguaggio, perchè ci permette di definire le funzioni con la massima libertà nel dare i nomi alle variabili al loro interno, senza doverci preoccupare che nel nostro script (o in qualche altra funzione) ci siano variabili con lo stesso nome il cui valore potrebbe risultare alterato. Questo significa, per tornare all'esempio precedente, che se avessimo scritto print $num2 all'esterno della funzione il_maggiore(), non avremmo ottenuto alcun risultato, e anzi avremmo ricevuto un errore di tipo notice, in quanto la variabile $num2, in quell'ambito, non è definita.

Le variabili utilizzate all'interno di una funzione si chiamano variabili locali. Le variabili utilizzate dallo script principale, invece, sono dette variabili globali.

Normalmente, quindi, se una funzione ha bisogno di un certo dato, è sufficiente includerlo tra i parametri che le dovranno essere passati. Tuttavia, esiste una possibilità per consentire ad una funzione di vedere una variabile globale: si tratta di dichiararla attraverso l'istruzione global.

function stampa($var1, $var2) {
global $a;
print $a;
}
$a = 'ciao a tutti';
$b = 'buongiorno';
$c = 'arrivederci';
stampa($b, $c);
Questo codice, dopo avere definito la funzione stampa(), assegna un valore a tre variabili globali: $a, $b e $c. Viene poi chiamata la funzione stampa(), passandole i valori di $b e $c, che nella funzione si chiamano $var1 e $var2 ma che al suo interno non vengono utilizzati. Viene invece dichiarata la variabile globale $a, che è valorizzata con la stringa 'ciao a tutti', e quindi questo è ciò che viene stampato a video dall'istruzione print. Se non ci fosse l'istruzione "global $a", la variabile $a risulterebbe non definita all'interno della funzione, e quindi la print genererebbe un errore.

Noi comunque sconsigliamo di utilizzare le variabili globali in questo modo, perchè fanno perdere chiarezza allo script e alla funzione stessa.

Termine della funzione e valore restituito. Abbiamo visto in precedenza che la funzione termina con l'istruzione return, la quale può anche essere utilizzata per restituire un valore. Nel caso in cui non sia scopo della funzione quello di restituire un valore, utilizzeremo semplicemente return. Viceversa, nel caso in cui volessimo restituire più di un valore, siccome la sintassi di PHP ci consente di restituire una sola variabile, potremo utilizzare un array. Vediamo un esempio, immaginando una funzione il cui scopo sia quello di ricevere un numero e di restituire il suo doppio, il suo triplo e il suo quintuplo:

function multipli($num) {
$doppio = $num * 2;
$triplo = $num * 3;
$quintuplo = $num * 5;
$ris = array($doppio, $triplo, $quintuplo);
return $ris;
}
Con questo sistema siamo riusciti a restituire tre valori da una funzione, pur rispettando la sintassi che ne prevede uno solo. Ovviamente quando richiameremo la funzione dovremo sapere che il risultato riceverà un array:

$a = 7;
$mul = multipli($a); // $mul sarà un array a 3 elementi
Se ci interessa, possiamo anche usare un costrutto del linguaggio per distribuire immediatamente i tre valori su tre variabili distinte:

list($doppio, $triplo, $quintuplo) = multipli($a);
Il costrutto list() serve ad assegnare i valori di un array (quello indicato a destra dell'uguale) ad una serie di variabili che gli passiamo fra parentesi. Ovviamente è possibile utilizzarlo non solo per "raccogliere" il risultato di una funzione, ma con qualsiasi array:

$arr = array('Marco','Paolo','Luca');
list($primo, $secondo, $terzo) = $arr;
In questo caso, $primo prenderà il valore 'Marco', $secondo il valore 'Paolo', $terzo il valore 'Luca'.

Un'ulteriore precisazione: poco fa abbiamo detto che la funzione termina con l'istruzione return. In realtà ciò non è necessario: infatti, nel caso in cui non ci siano valori da restituire, possiamo anche omettere l'istruzione return, e l'esecuzione della funzione terminerà quando arriverà in fondo al codice relativo, restituendo il controllo allo script principale (o ad un'altra funzione che eventualmente l'ha chiamata).

Argomenti facoltativi

In determinate situazioni possiamo prevedere delle funzioni in cui non è obbligatorio che tutti gli argomenti previsti vengano passati al momento della chiamata. Abbiamo visto, infatti, nella lezione precedente, che alcune funzioni di PHP prevedono dei parametri facoltativi. La stessa cosa vale per le funzioni definite da noi: se infatti, al momento in cui definiamo le funzioni, prevediamo un valore di default per un certo parametro, quel parametro diventerà facoltativo in fase di chiamata della funzione, e, nel caso manchi, la funzione utilizzerà il valore di default.

Come esempio consideriamo una funzione che stampa i dati anagrafici di una persona:

function anagrafe($nome, $indirizzo, $cf='non disponibile') {
print "Nome: $nome<br />";
print "Indirizzo: $indirizzo<br />";
print "Codice fiscale: $cf<br />";
}
Questa funzione prevede tre parametri in input, ma per il terzo è previsto un valore di default (la stringa 'non disponibile'). Quindi, se la funzione viene chiamata con soltanto due argomenti, la variabile $cf avrà proprio quel valore; se invece tutti e tre gli argomenti vengono indicati, il valore di default viene ignorato. Vediamo due esempi di chiamata di questa funzione:

anagrafe('Mario Rossi', 'via Roma 2', 'RSSMRA69S12A944X');
anagrafe('Paolo Verdi', 'via Parigi 9');
Nel primo caso otterremo questo output a video:

Nome: Mario Rossi
Indirizzo: via Roma 2
Codice fiscale: RSSMRA69S12A944X
Nel secondo caso:

Nome: Paolo Verdi
Indirizzo: via Parigi 9
Codice fiscale: non disponibile
Nella seconda occasione il codice fiscale non è stato passato, e la funzione ha utilizzato il valore di default.

Le variabili Get e POST


La principale peculiarità del web dinamico, come abbiamo detto all'inizio di questa guida, è la possibilità di variare i contenuti delle pagine in base alle richieste degli utenti. Questa possibilità si materializza attraverso i meccanismi che permettono agli utenti, oltre che di richiedere una pagina ad un web server, anche di specificare determinati parametri che saranno utilizzati dallo script PHP per determinare quali contenuti la pagina dovrà mostrare. Come esempio, possiamo immaginare una pagina il cui scopo è quello di visualizzare le caratteristiche di un dato prodotto, prelevandole da un database nel quale sono conservati i dati di un intero catalogo. Nel momento in cui si richiama la pagina, si dovrà specificare il codice del prodotto che deve essere visualizzato, per consentire allo script di prelevare dal database i dati di quel prodotto e mostrarli all'utente.

In alcuni casi, i dati che devono essere trasmessi allo script sono piuttosto numerosi: pensiamo ad esempio ad un modulo di registrazione per utenti, nel quale vengono indicati nome, cognome, indirizzo, telefono, casella e-mail ed altri dati personali. In questo caso lo script, dopo averli ricevuti, andrà a salvarli nel database.

In questa lezione non ci occuperemo di come vengono salvati o recuperati i dati da un database, ma del modo in cui PHP li riceve dall'utente. Esistono due sistemi per passare dati ad uno script: il metodo GET e il metodo POST.

Il metodo GET

Il metodo GET consiste nell'accodare i dati all'indirizzo della pagina richiesta, facendo seguire il nome della pagina da un punto interrogativo e dalle coppie nome/valore dei dati che ci interessano. Nome e valore sono separati da un segno di uguale. Le diverse coppie nome/valore sono separate dal segno '&'. Quindi, immaginando di avere la pagina prodotto.php che mostra le caratteristiche di un prodotto passandole il codice e la categoria del prodotto stesso, diciamo che, per visualizzare i dati del prodotto A7 della categoria 2, dovremo richiamare la pagina in questo modo:

<a href="prodotto.php?cod=a7&cat=2">
La stringa che si trova dopo il punto interrogativo, contenente nomi e valori dei parametri, viene detta query string. Quando la pagina prodotto.php viene richiamata in questo modo, essa avrà a disposizione, al suo interno, le variabili $_GET['cod'] (con valore 'a7') e $_GET['cat'] (con valore '2'). Infatti i valori contenuti nella query string vengono memorizzati da PHP nell'array $_GET, che è un array superglobale in quanto è disponibile anche all'interno delle funzioni.

Quindi, per tornare all'esempio del catalogo, possiamo immaginare di avere una pagina nella quale mostriamo una tabella con il nome di ogni prodotto su una riga, e, di fianco, il link che ci permette di visualizzare le caratteristiche di quel prodotto. In ogni riga, quindi, questo link richiamerà sempre la pagina prodotto.php, valorizzando ogni volta i diversi valori di 'cod' e 'cat'.

Il metodo POST

Il metodo POST viene utilizzato con i moduli: quando una pagina HTML contiene un tag <form>, uno dei suoi attributi è method, che può valere GET o POST. Se il metodo è GET, i dati vengono passati nella query string, come abbiamo visto prima. Se il metodo è POST, i dati vengono invece inviati in maniera da non essere direttamente visibili per l'utente, attraverso la richiesta HTTP che il browser invia al server.

I dati che vengono passati attraverso il metodo POST sono memorizzati nell'array $_POST. Anche questo array, come $_GET, è un array superglobale. Quindi, per fare un esempio attraverso un piccolo modulo:

<form action="elabora.php" method="post">
<input type="text" name="nome">
<input type="checkbox" name="nuovo" value="si">
<input type="submit" name="submit" value="invia">
</form>
Questo modulo contiene semplicemente una casella di testo che si chiama 'nome' e una checkbox che si chiama 'nuovo', il cui valore è definito come 'sì'. Poi c'è il tasto che invia i dati, attraverso il metodo POST, alla pagina elabora.php.

Questa pagina si troverà a disposizione la variabile $_POST['nome'], contenente il valore che l'utente ha digitato nel campo di testo; inoltre, se è stata selezionata la checkbox, riceverà la variabile $_POST['nuovo'] con valore 'si'. Attenzione però: se la checkbox non viene selezionata dall'utente, la variabile corrispondente risulterà non definita.

Abbiamo visto quindi, brevemente, in che modo recuperare i dati che gli utenti ci possono trasmettere. C'è da dire che, modificando l'impostazione register_globals su php.ini, sarebbe possibile anche recuperare i dati in maniera più semplice. Infatti, se register_globals è attiva ('on'), oltre agli array visti sopra avremo anche delle variabili globali che contengono direttamente i valori corrispondenti. Ad esempio, nel primo esempio avremmo a disposizione la variabile $cod e la variabile $cat, nel secondo avremmo la variabile $nome e la variabile (eventuale) $nuovo. Fino a qualche tempo fa, erano in molti a lavorare in questo modo, perchè il valore di register_globals, di default, era attivo, e quindi buona parte dei programmatori PHP, soprattutto agli inizi, trovavano più naturale utilizzare il sistema più immediato.

A partire dalla versione 4.2.0 di PHP, fortunatamente, il valore di default di register_globals è stato cambiato in off, e gli sviluppatori di PHP sconsigliano di rimetterlo ad on per gravi problemi di sicurezza. Questo perchè, utilizzando gli array superglobali $_GET e $_POST, si rende il codice più chiaro e anche più sicuro. Se vi dovesse capitare di utilizzare degli script già fatti e doveste notare dei malfunzionamenti, potrebbe dipendere dal fatto che tali script utilizzano le variabili globali invece degli array superglobali, ed il vostro register_globals è a off.

Un'ultima annotazione: gli array $_GET e $_POST sono stati introdotti nella versione 4.1.0 di PHP. In precedenza, gli stessi valori venivano memorizzati negli array corrispondenti $HTTP_GET_VARS e $HTTP_POST_VARS, che però non erano superglobali. Questi array sono disponibili anche nelle versioni attuali di PHP, ma il loro uso è sconsigliato, ed è presumibile che in futuro scompariranno.

Le variabili superglobali definite automaticamente da PHP non permettono solamente di accedere ai parametri passati alla pagina, ma esistono variabili che permettono di accedere ad altri valori molto importanti.

La variabile $_SERVER contiene informazioni sul server corrente, recuperate attraverso Apache o estratte dagli header della pagina valorizzati dal browser dell'utente che sta navigando. Spesso i valori contenuti in questo array associativo vengono utilizzati per comprendere da dove proviene una richiesta, rilevare l'indirizzo IP che identifica il PC da cui l'utente è acceduto alla nostra pagina oppure conoscere il path di base dell'applicativo.

Le variabili $_COOKIE e $_SESSION (che verranno analizzate successivamente in modo più approfondito) contengono rispettivamente i valori dei cookie e delle sessioni valide per una determinata pagina. I valori vengono acceduti utilizzando come chiave il nome del cookie/sessione che si decide interrogare.

La variabile $_FILES è molto importante perchè contiene informazioni su tutti i file inviati alla pagina attraverso un form. L'array $_FILES ha una struttura che permette di recuperare (sempre attraverso il nome del parametro, come per le variabili $_POST e $_GET) il nome del file caricato, le sue dimensioni ed il nome del file temporaneo salvato su disco sul quale è possibile operare.

Mantenere lo stato: i cookie

Un cookie è una coppia chiave/valore avente una data di scadenza ed un dominio di validità che viene salvata sul PC dell'utente ed inviata (attraverso appositi header HTTP) ad ogni pagina dalla quale possa essere acceduta.

Grazie ai cookie è possibile identificare con buona sicurezza le credenziali di un utente che accede ad una pagina, oppure salvare dei dati per un successivo recupero. Per esempio si potrebbe salvare su un cookie un valore indicante l'ultima pagina visualizzata, in modo da occuparsi di ridirigere l'utente all'ultima pagina visualizzata nel momento in cui si connettesse nuovamente al nostro sito.

La creazione di un cookie è un'operazione molto semplice, che in PHP può essere effettuata utilizzando un'unica chiamata alla funzione setcookie(). Questa funzione accetta un numero variabile di parametri. Nell'ordine:

Il nome del cookie
Il valore del cookie, che dovrà essere necessariamente un valore scalare (intero o stringa, gli array non possono essere salvati direttamente)
Un numero indicante la data di scadenza del cookie. Nel caso questo numero sia 0 o non specificato, il cookie durerà fino a che l'utente non chiuderà il suo browser. Nel caso in cui il timestamp specificato risulti in una data precedente a quella attuale, il cookie viene cancellato
Il path di validità del cookie
Il dominio di validità del cookie
Un parametro boolean che indica se trasmettere il cookie solamente attraverso una connessione sicura HTTPS
I cookie creati sono disponibili solamente dalla pagina successiva alla loro creazione.

Dato che la funzione setcookie() genera esplicitamente un header HTTP, è necessario che prima del suo utilizzo non sia stato stampato (usando echo, print o qualunque altro metodo di output) alcun valore, altrimenti verrà generato un errore. Anche una riga vuota all'inizio del file prima del tag di apertura PHP porterà alla generazione di questo errore.

Alcuni esempio di creazione di un cookie:

setcookie('prova_cookie', 'valore cookie', /* dura per un'ora */ time() + 3600);
setcookie('prova_2', 'ciao'); //cookie che dura fino a che l'utente non chiude il browser
Per cancellare un cookie è necessario utilizzare la stessa funzione specificando gli stessi parametri utilizzati in fase di creazione ma utilizzando una data di scadenza precedente a quella attuale.

setcookie('prova_cookie', '', time() - 3600);
Una volta creato un cookie il suo valore sarà accessibile attraverso $_COOKIE[$nome_cookie] nelle pagine successive a quella attuale, presupponendo che la data di scadenza non sia trascorsa e che siano rispettate le restrizioni di dominio e cartella.

È buona norma non creare troppi cookie, dato che i browser hanno un limite sia relativo ad uno specifico dominio che ad una specifica cartella. In caso fosse necessario mantenere molti valori, è preferibile salvarli su database o file e salvare nel cookie una chiave che ne permetta l'accesso nella pagine successive. I cookie sono facilmente recuperabili e leggibili, quindi è importante non salvare mai informazioni private o vitali, salvo previa criptazione.

Mantenere lo stato:le sessioni

Le sessioni permettono anch'esse di mantenere informazioni relative all'utente tra le varie pagine navigate, ma rispetto ai cookie danno la possibilità di salvare arbitrari tipi di dato (non solo stringhe e numeri) e, se PHP è impostato correttamente, di non preoccuparsi dell'identificazione dell'utente.

Quando un utente accede per la prima volta ad una pagina PHP impostata per creare una sessione, a questi viene associato un ID univoco che verrà utilizzato da PHP come chiave per recuperare l'array $_SESSION salvato specificamente per il determinato utente. L'ID è un codice univoco che, al momento della creazione della sessione, viene salvato automaticamente da PHP all'interno di un cookie oppure, se i cookie risultano disabilitati, accodato agli URL relativi generati dallo script PHP.

In questo modo il programmatore può occuparsi solamente di inizializzare la sessione e salvare i propri dati. Ovviamente questo comportamento può essere controllato attraverso le impostazioni del file php.ini; potrebbe capitare quindi che il passaggio automatico dell'ID di sessione attraverso gli URL relativi non sia abilitato. In questo caso PHP ci viene incontro generando una costante chiamata SID che contiene la chiave di sessione preceduta dal nome. Basta accodare questa costante ai nostri URL per avere un sistema perfettamente funzionante.

L'inizializzazione di una sessione, come già accennato, viene fatta automaticamente da PHP. A noi basterà scrivere:

$_SESSION['nome'] = $valore;
per assicurarci che la variabile di sessione 'nome' abbia il valore assegnato, e che questo valore sia specifico per l'utente che ha appena eseguito la pagina che contiene il codice.

Non mi addentro nel dettaglio, e vi lascio alla lettura degli articoli di HTML.it, dedicati sia alle sessioni sia ai cookie, che trattano l'argomento in modo molto approfondito.

Le sessioni sono un argomento a prima vista molto semplice, ma spesso ci si trova in situazioni nelle quali è necessario controllare completamente il comportamento dei processi di salvataggio, lettura, creazione e distruzione delle sessioni. A questo scopo ci vengono in aiuto una serie di configurazioni del file php.ini ed una serie di funzioni aggiuntive che, anche se non tratterò in questa guida base, consiglio caldamente di studiare ed analizzare.

Accedere ai file

Uno degli aspetti fondamentali della programmazione è quello di poter accedere a fonti di dato esterne al fine di recuperare o salvare delle informazioni utili ai fini della nostra applicazione. PHP, come tutti i linguaggi di programmazione, fornisce una ricca libreria per l'accesso ai file ed alle risorse presenti sul server. Con l'avvento di PHP 5, è stato aggiunto anche il supporto a particolari tipi di risorse, chiamate stream, in modo che sia possibile accedere a qualunque tipo di fonte come se si stesse accedendo ad un file (un po' come accade in Linux, dove la maggior parte dei sistemi di input/output hardware possono essere letti e scritti come se fossero file).

Le operazioni principali sui file sono essenzialmente quelle di lettura, scrittura e posizionamento (PHP fornisce moltissime operazioni ausiliarie per gestire completamente i file, come operazioni per l'eliminazione e la prova d'esistenza, che analizzeremo in modo più approfondito in seguito). La maggior parte delle operazioni effettuate sui file avvengono applicando delle funzioni che accettano come parametro una risorsa che rappresenta il file. La risorsa (recuperata con fopen, come vedremo in seguito) è un tipo di dato speciale gestito internamente da PHP, che serve al motore del linguaggio di programmazione come indicativo per delle informazioni a basso livello richieste per il corretto funzionamento della libreria utilizzata.

Vediamo un piccolo esempio:

<?php

//Presuppongo che la directory corrente abbia i permessi corretti

$fp = fopen('prova.txt', 'w+'); //Apro il file prova.txt in lettura, lo creo se non esiste
fwrite($fp, ciao a tutti, come va?); //Scrivo una stringa sul file
fclose($fp); //Chiudo il file aperto precedentemente

?>
Il programma precedente è molto semplice: crea un file prova.txt, vi scrive dentro "ciao a tutti, come va?" e lo chiude. L'operazione di apertura di un file avviene attraverso la funzione fopen che accetta, nella sua forma base, due parametri: il primo rappresenta il percorso (path) del file sul quale vorremmo operare. Il secondo è una stringa che indica alla funzione quali sono le operazioni che si desiderano svolgere sul file. Per una lista dettagliata di queste rimando alla documentazione ufficiale, ma le più importanti sono:

'r' Apre in sola lettura. Posiziona il puntatore all'inizio del file.
'r+' Apre in lettura e scrittura. Posiziona il puntatore all'inizio del file.
'w' Apre il file in sola scrittura. Posiziona il puntatore all'inizio del file e tronca il file alla lunghezza zero. Se il file non esiste, tenta di crearlo.
'w+' Apre in lettura e scrittura. Posiziona il puntatore all'inizio del file e tronca il file alla lunghezza zero. Se il file non esiste, tenta di crearlo.
'a' Apre in sola scrittura. Posiziona il puntatore alla fine del file. Se il file non esiste, tenta di crearlo.
'a+' Apre in lettura e scrittura. Posiziona il puntatore alla fine del file. Se il file non esiste, tenta di crearlo.
Come è possibile notare dalla descrizione dei parametri elencati precedentemente, si fa riferimento al puntatore di un file. Il puntatore non è altro che un indicatore numerico che specifica la posizione attuale all'interno del file dalla quale verranno eseguite le operazioni richieste. Il posizionamento del puntatore avviene tramite la funzione fseek, che accetta come parametri la risorsa del file, un numero di byte, ed una costante che indica se il numero di byte è assoluto (SEEK_SET), se deve essere aggiunto alla posizione corrente (SEEK_CUR) oppure se deve essere aggiunto alla fine del file (SEEK_END).

Un semplice esempio per chiarire:

<?php

// Apro il file prova.txt in scrittura e lo riempio con 10 righe di testo
$fp = fopen(prova.txt, w+);
for($i = 0; $i < 10; ++$i)
{
fwrite($fp, Stringa di prova numero .$i.\n);
}
fclose($fp);

// Ora apro il file in lettura, mi muovo al suo interno, e stampo parti di contenuto
$fp = fopen(prova.txt, r);
fseek($fp, 10, SEEK_SET); //Mi posiziono al 10° carattere
$prova = fread($fp, 20); //Leggo 20 caratteri partendo dalla posizione corrente
echo $prova;
echo "<br />";
echo "La posizione del puntatore all'interno del file è: ".ftell($fp);
fclose($fp);

?>
Nel codice precedente ho aperto in scrittura prova.txt e l'ho riempito un file con 10 righe di testo. Poi, dopo averlo chiuso, l'ho nuovamente aperto in lettura, ho spostato il puntatore di 10 posizioni, ho letto 20 caratteri con la funzione fread ed ho stampato la stringa letta seguita dalla nuova posizione del puntatore (10 + 20 = 30). La funzione ftell accetta solamente la risorsa rappresentante il file e restituisce la posizione del puntatore al suo interno, mentre la funzione fread accetta come secondo parametro il numero di byte da leggere. Dopo la lettura il puntatore verrà spostato del numero di byte specificato. Giocate un po' con queste funzioni per capirne il corretto funzionamento.

Utilizzare SQLite

Per molti anni PHP è stato affiancato al database MySQL. Possiamo quasi dire che la loro crescita è stata parallela ed ha portato grossi miglioramenti nel campo delle applicazioni web opensource. Per molto tempo quindi con PHP è stato fornito nativamente il supporto alle librerie per l'accesso a MySQL. Purtroppo il cambio di licenza di quest'ultimo ha obbligato gli sviluppatori a rimuovere il supporto nativo per MySQL (anche se la libreria è sempre in evoluzione e distribuita).

Al fine di aiutare comunque coloro che necessitano di un database ma hanno solamente accesso alla configurazione minima di PHP, gli sviluppatori hanno deciso di implementare nativamente il supporto ad un altro sistema di database: SQLite. Questo sistema, cui abbiamo dedicato un ampio approfondimento, si differenzia molto da MySQL dato che non si basa su un'architettura client server ed è stato sviluppato appositamente per permettere l'accesso molto veloce ai dati. I database creati sono contenuti in un unico file binario (possono anche essere creati database temporanei salvati in memoria) che può essere acceduto tramite le funzioni fornite dalla libreria per eseguirvi query SQL.

La libreria SQLite fornisce un'interfaccia sia ad oggetti sia procedurale. Dato che il compito di questa guida introduttiva non comprende la trattazione delle programmazione ad oggetti, ci occuperemo dell'interfaccia a funzioni. Per chi fosse interessato a MySQL rimandiamo alla guida

Per operare su un database è necessario recuperare una risorsa (un po' come abbiamo visto precedentemente per i file) e lavorare su questa con delle funzioni apposite. La risorsa connessa ad un database può essere recuperata utilizzando sqlite_open:

$sq = sqlite_open("miodb.db", 0666, $sqlite_error);
Il primo parametro è il nome del file che conterrà i nostri dati (se non esiste verrà creato), il secondo indica i permessi da associare al database (attualmente il parametro viene ignorato da SQLite anche se l'impostazione consigliata è 0666) mentre il terzo conterrà eventualmente una stringa con il messaggio di errore eventualmente riscontrato durante l'apertura della fonte di dati. In caso sia andato tutto per il verso giusto, $sq conterrà la risorsa che ci permetterà di accedere al database miodb.db, altrimenti assumerà un valore nullo. Per questo motivo è sempre buona prassi controllare il valore restituito da sqlite_open prima di proseguire.

Per effettuare una query sul database possiamo utilizzare la funzione sqlite_query, ed analizzare il risultato eventualmente ottenuto (per esempio in caso di operazioni di selezione) attraverso sqlite_fetch_array. Un semplice esempio:

$sq = sqlite_open("miodb.db", 0666, $sqlite_error);
if(!$sq)
{
die("Errore Sqlite: ".$sqlite_error);
}

sqlite_query($sq, "CREATE TABLE prova_tbl (campo varchar(10))");
for($i = 0; $i < 10; ++$i)

{
sqlite_query($sq, "INSERT INTO prova_tbl VALUES ('Prova ".$i."')");
}

$result = sqlite_query($sq, "SELECT * FROM prova_tbl");
while($data = sqlite_fetch_array($result))

{
echo $data['campo']."<br />";
}
sqlite_close($sq);
Nel codice precedente ci siamo connessi al database, abbiamo controllato che non ci fossero errori ed abbiamo eseguito delle query sulla risorsa recuperata. La prima query ha creato una tabella di nome prova_tbl con un campo di nome "campo"; la seconda, eseguita all'interno di un ciclo, si è occupata di inserire dieci valori nella tabella mentre la terza ha recuperato tutti questi valori. All'interno del ciclo while abbiamo recuperato una dopo l'altra le singole righe selezionate ed abbiamo stampato i valori del campo "campo". Come possiamo notare la funzione sqlite_fetch_array restituisce la prossima riga selezionata oppure FALSE nel caso in cui quella precedente fosse l'ultima.

Come è stato possibile notare da questa breve introduzione, SQLite si comporta in modo molto simile ad un database relazionale, con la differenza che non opera in un'architettura client / server e permette l'esecuzione di query molto semplici e compatte.

Una funzionalità molto interessante della libreria, che mi sento di dover trattare prima di chiudere, è quella che permette di registrare delle funzioni PHP da richiamare all'interno delle proprie query SQL. Vediamo un semplice esempio:

function trim_upper($string)
{
return strtoupper(trim($string));
}

$sq = sqlite_open("miodb.db", 0666, $sqlite_error);
if(!$sq)
{
die("Errore Sqlite: ".$sqlite_error);
}

sqlite_create_function($sq, "trimup", "trim_upper", 1);
$result = sqlite_query($sq, "SELECT trimup(campo) AS campo FROM prova_tbl");
while($data = sqlite_fetch_array($result))
{
echo $data['campo']."<br />";
}
sqlite_close($sq);
Il codice accede al database che abbiamo creato precedentemente e recupera tutte le righe applicando direttamente da SQL la funzione trim_upper (che elimina gli spazi all'inizio ed alla fine e rende la stringa maiuscola) al campo selezionato. La funzione viene registrata attraverso sqlite_create_function che accetta come parametri la risorsa rappresentante il database, il nome da utilizzare all'interno dell'SQL per richiamare la funzione passata come terzo argomento ed infine il numero di parametri accettati. Grazie a questa interessante funzionalità si può estendere il linguaggio SQL utilizzato da SQLite con un insieme di funzioni adatte a compiere le operazioni più ripetitive sui dati, al fine di rendere il codice più ordinato e pulito.

Interrogare database MySQL

In PHP 5 abbiamo diverse soluzioni per connetterci ai database. Uno dei database più utilizzati in ambito opensource è sicuramente MySQL, che conta dalla sua una larga schiera di sviluppatori e supporters. In PHP 5 possiamo accedere a MySQL attraverso i layer di astrazione distribuiti nella release standard (PDO ed SDO), ma anche utilizzando la libreria mysql (quella utilizzata anche nella versione precedente di PHP) e la nuova libreria mysqli che fornisce un supporto più completo al linguaggio ed espone un'interfaccia ad oggetti.

Date lo modifiche apportate al linguaggio che puntano a muovere il paradigma di programmazione tipico di PHP da strutturato ad oggetti, mi pare una buona scelta imparare a conoscere la libreria mysqli utilizzando la sua interfaccia a classi piuttosto che basarsi sull'approccio a funzioni.

La connessione ad un database mysql prevede la creazione di un oggetto mysqli tramite il quale effettueremo le nostre operazioni di interrogazione e gestione del database:

<?php
$mysqli = new mysqli('host', 'username', 'password', 'dbname');
// ... eseguiamo le nostre operazioni ...
$mysqli->close();
?>
Una volta istanziato un oggetto mysqli possiamo operare su di esso:

<?php
// ... connessione

$mysqli->autocommit(true);
$mysqli->query("
CREATE TABLE test (
id INT UNSIGNED AUTO_INCREMENT NOT NULL,
title VARCHAR(32) NOT NULL,
content TEXT NOT NULL,
PRIMARY KEY(id)
);
");

// Inseriamo qualche informazione

for($i = 0; $i < 1000; ++$i)

{
$query = sprintf("INSERT INTO test (title, content) VALUES ('%s', '%s')", "Titolo ".$i, "Contenuto di prova ".$i);
$mysqli->query($query);
}


// Selezioniamo e stampiamo le righe inserite

$result = $mysqli->query("SELECT * FROM test", MYSQLI_USE_RESULT);

while($row = $result->fetch_assoc())

{
printf("<h3>%s</h3><p>%s</p><hr />", $row['title'], $row['content']);
}

$result->close();

// ....

?>
I metodi utilizzati nell'esempio precedente sono i seguenti:

void autocommit(bool): permette di impostare l'oggetto in modo che richiami automaticamente il metodo commit() dopo aver effettuato una query. In caso sia impostato a false e si stia operando su tabelle che supportano le transizioni, è necessario richiamare commit manualmente per applicare le modifiche apportate dalle query;
mixed query(string[, int]): esegue una query SQL sul database utilizzato. Il risultato restituito dipende dalla tipologia di query eseguita: nel caso la query SELECT, SHOW, EXPLAIN o DESCRIBE viene restituito un oggetto (di cui analizzeremo le proprietà successivamente) altrimenti viene restituito true in caso di query eseguita correttamente, false in caso contrario. Il secondo parametro passato al metodo può essere la c
fonte by:italian web side