3. Le basi di PHP
3.1. Un primo esempio
Di seguito è riportato un programma che illustra le prime caratteristiche di PHP.
3.1.1. Il programma (exemple_01)
<?php
// questo è un commento
// variabile utilizzata senza essere stata dichiarata
$nom = "dupont";
// un messaggio a schermo
print "nom=$nom\n";
// un array con elementi di tipo diverso
$tableau = array("un", "deux", 3, 4);
// il numero dei suoi elementi
$n = count($tableau);
// un ciclo
for ($i = 0; $i < $n; $i++)
print "tableau[$i]=$tableau[$i]\n";
// inizializzazione di 2 variabili con il contenuto di un array
list($chaine1, $chaine2) = array("chaine1", "chaine2");
// concatenazione delle 2 stringhe
$chaine3 = $chaine1 . $chaine2;
// visualizzazione del risultato
print "[$chaine1,$chaine2,$chaine3]\n";
// utilizzo di una funzione
affiche($chaine1);
// il tipo di una variabile può essere noto
afficheType($n);
afficheType($chaine1);
afficheType($tableau);
// il tipo di una variabile può cambiare durante l'esecuzione
$n = "a changé";
afficheType($n);
// una funzione può restituire un risultato
$res1 = f1(4);
print "res1=$res1\n";
// una funzione può restituire un array di valori
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";
// si sarebbero potuti recuperare questi valori in un array
$t = f2();
for ($i = 0; $i < count($t); $i++)
print "t[$i]=$t[$i]\n";
// test
for ($i = 0; $i < count($t); $i++)
// visualizza solo i canali
if (getType($t[$i]) == "string")
print "t[$i]=$t[$i]\n";
// altri test
for ($i = 0; $i < count($t); $i++){
// visualizza solo i numeri interi >10
if (getType($t[$i]) == "integer" and $t[$i] > 10)
print "t[$i]=$t[$i]\n";
}
// un ciclo while
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
print "t[$i]=$t[$i]\n";
$somme+=$t[$i]; //$somme=$somme+$t[$i]
$i++; //$i=$i+1
}
print "somme=$somme\n";
// fine programma
exit;
//----------------------------------
function affiche($chaine) {
// visualizza $chaine
print "chaine=$chaine\n";
}
//----------------------------------
function afficheType($variable) {
// visualizza il tipo di $variable
print "type[$variable]=" . getType($variable) . "\n";
}
//----------------------------------
function f1($param) {
// aggiunge 10 a $param
return $param + 10;
}
//----------------------------------
function f2() {
// restituisce 3 valori
return array("un", 0, 100);
}
?>
I risultati:
Commenti
- riga 5: in PHP, non viene dichiarato il tipo delle variabili. Queste hanno un tipo dinamico che può variare nel tempo
- $nom rappresenta la variabile con identificatore nom
- riga 8: per scrivere sullo schermo, è possibile utilizzare l'istruzione print o l'istruzione echo
- riga 11: la parola chiave array consente di definire un array. La variabile $nom[$i] rappresenta l'elemento $i dell'array $tableau.
- riga 14: la funzione count($tableau) restituisce il numero di elementi dell'array $tableau
- riga 18: le stringhe di caratteri sono racchiuse tra virgolette " o apostrofi '. All'interno delle virgolette, le variabili $variable vengono valutate, ma non all'interno degli apostrofi.
- riga 21: la funzione list consente di raggruppare variabili in un elenco e di assegnare loro un valore con un'unica operazione di assegnazione. In questo caso $chaine1="stringa1" e $chaine2="stringa2".
- riga 24: l'operatore . è l'operatore di concatenazione delle stringhe.
- riga 88: la parola chiave function definisce una funzione. Una funzione restituisce o meno valori tramite l’istruzione return. Il codice chiamante può ignorare o recuperare i risultati di una funzione. Una funzione può essere definita in qualsiasi punto del codice.
- riga 90: la funzione predefinita getType($variable) restituisce una stringa di caratteri che rappresenta il tipo di $variable. Questo tipo può cambiare nel tempo.
- riga 79: la funzione predefinita exit interrompe lo script.
3.2. L'ambito delle variabili
3.2.1. Programma 1 (exemple_02)
<?php
// ambito delle variabili
function f1() {
// si utilizza la variabile globale $i
$i = &$GLOBALS["i"];
$i++;
$j = 10;
print "f1[i,j]=[$i,$j]\n";
}
function f2() {
// si utilizza la variabile globale $i
$i = &$GLOBALS["i"];
$i++;
$j = 20;
print "f2[i,j]=[$i,$j]\n";
}
function f3() {
// si utilizza una variabile locale $i
$i = 4;
$j = 30;
print "f3[i,j]=[$i,$j]\n";
}
// test
$i = 0;
$j = 0; // queste due variabili sono note a una funzione f tramite l'array $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>
I risultati:
Commenti
- righe 29-30: definiscono due variabili, $i e $j, del programma principale. Queste variabili non sono note all'interno delle funzioni. Pertanto, alla riga 9, la variabile $j della funzione f1 è una variabile locale della funzione f1 ed è diversa dalla variabile $j del programma principale. Una funzione può accedere a una variabile $variable del programma principale tramite un array di variabili globali denominato $GLOBALS. Alla riga 7, la notazione $GLOBALS["i"] indica la variabile globale $i del programma principale. Se scriviamo
alla variabile locale $i viene assegnato il valore della variabile globale $i. Si tratta di due variabili diverse e la modifica della variabile locale $i non modificherà la variabile globale $i. La notazione
fa sì che la variabile locale $i abbia lo stesso indirizzo di memoria della variabile globale $i. Modificare la variabile locale $i equivale quindi a modificare la variabile globale $i.
3.2.2. Programma 2 (exemple_03)
<?php
// l'ambito di una variabile è globale ai blocchi di codice
$i = 0; {
$i = 4;
$i++;
}
print "i=$i\n";
?>
I risultati:
Commenti
In alcuni linguaggi, una variabile definita all'interno di parentesi graffe ha un ambito limitato a queste ultime: non è visibile al di fuori di esse. I risultati sopra riportati dimostrano che in PHP non è così. La variabile $i definita alla riga 5 all'interno delle parentesi graffe è la stessa utilizzata alle righe 4 e 8 al di fuori di esse.
3.3. Le tabelle
3.3.1. Tabelle classiche unidimensionali (exemple_04)
<?php
// array classici
// inizializzazione
$tab1 = array(0, 1, 2, 3, 4, 5);
// iterazione - 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// iterazione - 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
print "tab1[$clé]=$valeur\n";
// aggiunta di elementi
$tab1[] = $i++;
$tab1[] = $i++;
// percorso - 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
print "tab1[$i]=$élément\n";
$i++;
}
// eliminazione dell'ultimo elemento
array_pop($tab1);
// percorso - 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// eliminazione del primo elemento
array_shift($tab1);
// percorso - 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// aggiunta alla fine della tabella
array_push($tab1, -2);
// percorso - 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// aggiunta all'inizio della tabella
array_unshift($tab1, -1);
// percorso - 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
?>
I risultati:
Commenti
Il programma sopra riportato illustra le operazioni di manipolazione di un array di valori. Esistono due notazioni per gli array in PHP:
L'array 1 è denominato array, mentre l'array 2 è un dizionario in cui gli elementi sono indicati come chiave => valore. La notazione $contraires["beau"] indica il valore associato alla chiave "bello". In questo caso si tratta della stringa "brutto". L'array 1 è solo una variante del dizionario e potrebbe essere scritto come segue:
Si ottiene così $tableau[2]="tre". In definitiva, si tratta solo di dizionari. Nel caso di un array classico composto da n elementi, le chiavi sono i numeri interi dell’intervallo [0,n-1].
- riga 15: la funzione each($tableau) permette di iterare su un dizionario. Ad ogni chiamata, restituisce una coppia (chiave, valore) dello stesso.
- riga 14: la funzione reset($dictionnaire) imposta la funzione each sulla prima coppia (chiave, valore) del dizionario.
- riga 15: il ciclo while termina quando la funzione each restituisce una coppia vuota alla fine del dizionario.
- riga 19: la notazione $tableau[]=valore aggiunge l’elemento valeur come ultimo elemento di $tableau.
- riga 25: l'array viene iterato con un foreach. Questo elemento sintattico consente di iterare un dizionario, quindi un array, secondo due sintassi:
La prima sintassi restituisce una coppia (clé,valeur) ad ogni iterazione, mentre la seconda sintassi restituisce solo l'elemento valeur del dizionario.
- riga 31: la funzione array_pop($tableau) rimuove l'ultimo elemento di $tableau
- riga 39: la funzione array_shift($tableau) rimuove il primo elemento da $tableau
- riga 47: la funzione array_push($tableau,valore) aggiunge valeur come ultimo elemento di $tableau
- riga 39: la funzione array_unshift($tableau,valore) aggiunge valeur come primo elemento di $tableau
3.3.2. Il dizionario (exemple_05)
<?php
// dizionari
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");
// percorso - 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// ordinamento del dizionario in base alla chiave
ksort($conjoints);
// percorso - 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// elenco delle chiavi del dizionario
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
print "clés[$i]=$clés[$i]\n";
// elenco dei valori del dizionario
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
print "valeurs[$i]=$valeurs[$i]\n";
// ricerca di una chiave
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");
// eliminazione di una coppia chiave-valore
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
print "conjoints[$clé]=$valeur\n";
}
// fine
exit;
function existe($conjoints, $mari) {
// verifica se la chiave $mari esiste nel dizionario $conjoints
if (isset($conjoints[$mari]))
print "La clé [$mari] existe associée à la valeur [$conjoints[$mari]]\n";
else
print "La clé [$mari] n'existe pas\n";
}
?>
I risultati:
Commenti
Il codice precedente applica a un dizionario quanto visto in precedenza per una semplice tabella. Commentiamo solo le novità:
- riga 13: la funzione ksort (key sort) consente di ordinare un dizionario in base all'ordine naturale delle chiavi.
- riga 21: la funzione array_keys($dictionnaire) restituisce l'elenco delle chiavi del dizionario sotto forma di tabella
- riga 26: la funzione array_values($dictionnaire) restituisce l'elenco dei valori del dizionario sotto forma di tabella
- riga 47: la funzione isset($variable) restituisce true se la variabile $variable è stata definita, false in caso contrario.
- riga 36: la funzione unset($variable) elimina la variabile $variable.
3.3.3. Le matrici multidimensionali (exemple_06)
<?php
// tabelle multidimensionali classiche
// inizializzazione
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// scorrimento
for ($i1 = 0; $i1 < count($multi); $i1++)
for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// dizionari multidimensionali
// inizializzazione
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// scorrimento
foreach ($multi as $clé => $valeur)
for ($i2 = 0; $i2 < count($valeur); $i2++)
print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>
Risultati:
Commenti
- riga 5: gli elementi dell'array $multi sono a loro volta array
- riga 12: l'array $multi diventa un dizionario (clé,valeur) in cui ogni valeur è un array
3.3.4. Collegamenti tra stringhe e tabelle (exemple_07)
<?php
// conversione da stringa a tabella
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);
// scorrimento tabella
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n";
// da array a stringa
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";
// aggiungiamo un campo vuoto
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// iterazione su array
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; // ora abbiamo 5 elementi, l'ultimo dei quali è vuoto
// aggiungiamo nuovamente un campo vuoto
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// iterazione dell'array
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; // ora abbiamo 6 elementi, gli ultimi due dei quali sono vuoti
?>
Risultati:
Commenti
- riga 5: la funzione explode($séparateur,$chaine) consente di recuperare i campi di $chaine separati da $séparateur. Pertanto, la funzione explode(":",$chaine) consente di recuperare sotto forma di array gli elementi di $chaine separati dalla stringa ":".
- La funzione implode($séparateur,$tableau) esegue l'operazione inversa rispetto alla funzione explode. Restituisce una stringa composta dagli elementi di $tableau separati da $séparateur.
3.4. Le stringhe
3.4.1. Notazione (exemple_08)
<?php
// notazione delle stringhe
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>
Risultati:
3.4.2. Confronto (exemple_09)
<?php
// test di confronto tra stringhe
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;
function compare($chaine1, $chaine2) {
// confronta stringa1 e stringa2
if ($chaine1 == $chaine2)
print "[$chaine1] est égal à [$chaine2]\n";
else
print "[$chaine1] est différent de [$chaine2]\n";
}
?>
Risultati:
3.5. Espressioni regolari (exemple_10)
<?php
// espressioni regolari in PHP
// estrazione dei diversi campi di una stringa
// il modello: una sequenza di cifre circondata da caratteri qualsiasi
// si desidera estrarre solo la sequenza di cifre
$modèle = "/(\d+)/";
// si confronta la stringa con il modello
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// il modello: una sequenza di cifre circondata da caratteri qualsiasi
// si desidera la sequenza di cifre insieme ai campi che la precedono e la seguono
$modèle = "/^(.*?)(\d+)(.*?)$/";
// si confronta la stringa con il modello
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// il modello: una data nel formato gg/mm/aa
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($modèle, "10/05/97");
compare($modèle, " 04/04/01 ");
compare($modèle, "5/1/01");
// il modello: un numero decimale
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($modèle, "187.8");
compare($modèle, "-0.6");
compare($modèle, "4");
compare($modèle, ".6");
compare($modèle, "4.");
compare($modèle, " + 4");
// fine
exit;
// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
// confronta la stringa $chaîne con il modello $modèle
// si confronta la stringa con il modello
$correspond = preg_match($modèle, $chaîne, $champs);
// visualizzazione dei risultati
print "\nRésultats($modèle,$chaîne)\n";
if ($correspond) {
for ($i = 0; $i < count($champs); $i++)
print "champs[$i]=$champs[$i]\n";
} else
print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
?>
Risultati:
Commenti
- righe 3-4: qui utilizziamo le espressioni regolari per estrarre i vari campi da una stringa di caratteri. Le espressioni regolari consentono di superare i limiti della funzione implode. Il principio consiste nel confrontare una stringa di caratteri con un’altra stringa denominata modèle utilizzando la funzione preg_match:
$correspond = preg_match($modèle, $chaîne, $champs);
La funzione preg_match restituisce un valore booleano se la stringa modèle è presente nella stringa chaîne. In caso affermativo, $champs[0] rappresenta la sottostringa corrispondente al modello. Inoltre, se il modello contiene sottomodelli tra parentesi, $champs[1] è la porzione di $chaîne corrispondente al primo sottomodello, $champs[2] è la parte di $chaîne corrispondente al secondo sottomodello, ecc...
Consideriamo il primo esempio. Il modello è definito alla riga 8: indica una sequenza di una o più (+) cifre (\d) posizionate in qualsiasi punto di una stringa. Inoltre, il modello definisce un sottomodello racchiuso tra parentesi.
- Riga 10: il modello /(\d+)/ (sequenza di una o più cifre in qualsiasi punto della stringa) viene confrontato con la stringa "xyz1234abcd". Si nota che la sottostringa 1234 corrisponde al modello. Si avrà quindi $champs[0] uguale a "1234". Inoltre, il modello contiene sottomodelli tra parentesi. Si avrà $champs[1] = "1234".
- riga 11: il modello /(\d+)/ viene confrontato con la stringa "12 34". Si nota che le sottostringhe 12 e 34 corrispondono al modello. Il confronto si interrompe alla prima sottostringa che corrisponde al modello. Si avrà quindi $champs[0]=12 e $champs[1]=12.
- riga 12: il modello /(\d+)/ viene confrontato con la stringa "abcd". Non viene trovata alcuna corrispondenza.
Spieghiamo i modelli utilizzati nel resto del codice:
$modèle = "/^(.*?)(\d+)(.*?)$/";
inizio della stringa (^), seguito da 0 o più (*) caratteri qualsiasi (.), poi 1 o più (+) cifre, e infine di nuovo 0 o più (*) caratteri qualsiasi (.). Il modello (.*) indica 0 o più caratteri qualsiasi. Un modello di questo tipo corrisponderà a qualsiasi stringa. Pertanto, il modello /^(.*)(\d+)(.*)$/ non verrà mai trovato poiché il primo sottomodello (.*) assorbirà l’intera stringa. Il modello (.*?)(\d+) indica invece 0 o più caratteri qualsiasi fino al sottomodello successivo (?), in questo caso \d+. Pertanto, le cifre non vengono più assorbite dal modello (.*). Il modello sopra riportato corrisponde quindi a [début de chaîne (^), une suite de caractères quelconques (.*?), une suite d'un ou plusieurs chiffres (\d+), une suite de caractères quelconques (.*?), la fin de la chaîne ($)].
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
corrisponde a [début de chaîne (^), 2 chiffres (\d\d), le caractère / (\/), 2 chiffres, /, 2 chiffres, une suite de 0 ou plusieurs espaces (\s*), la fin de chaîne ($)]
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
[début de chaîne (^), 0 ou plusieurs espaces (\s*), un signe + ou - [+|-] présent 0 ou 1 fois (?), une suite de 0 ou plusieurs espaces (\s*), 1 ou plusieurs chiffres suivis d'un point décimal suivi de zéro ou plusieurs chiffres (\d+\.\d*) ou (|) un point décimal (\.) suivi d'un ou plusieurs chiffres (\d+) ou (|) un ou plusieurs chiffres (\d+), une suite de 0 ou plusieurs espaces (\s*)].
3.6. Modalità di passaggio dei parametri delle funzioni (exemple_11)
<?php
// modalità di passaggio dei parametri
function f(&$i, $j) {
// $i sarà ottenuto per riferimento
// $j sarà ottenuto per valore
$i++;
$j++;
print "f[i,j]=[$i,$j]\n";
}
// ----------------------------------------test
$i = 0;
$j = 0;
// $i e $j passati per valore
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>
Risultati:
Commenti
Il codice sopra riportato mostra le due modalità di passaggio dei parametri a una funzione. Prendiamo il seguente esempio:
- riga 1: definisce i parametri formali $a e $b della funzione f. Quest'ultima elabora questi due parametri formali e restituisce un risultato.
- riga 7: chiamata della funzione f con due parametri effettivi $i e $j. I collegamenti tra i parametri formali ($a, $b) e i parametri effettivi ($i, $j) sono definiti dalla riga 7
- &$a: il simbolo & indica che il parametro formale $a assumerà come valore l’indirizzo del parametro effettivo $i. In altre parole, $a e $i sono due riferimenti alla stessa posizione di memoria. Modificare il parametro formale $a equivale a modificare il parametro effettivo $i. È quanto dimostra l’esecuzione del codice. Questa modalità di passaggio è adatta ai parametri di output e a dati di grandi dimensioni come array e dizionari. Questa modalità di passaggio è denominata «passaggio per riferimento».
- $b: il parametro formale $b assumerà il valore del parametro effettivo $j. Si tratta di un passaggio per valore. I parametri formali e quelli effettivi sono due variabili diverse. La modifica del parametro formale $b non ha alcuna incidenza sul parametro effettivo $j. È quanto dimostra l’esecuzione del codice. Questa modalità di passaggio è adatta ai parametri di ingresso.
- Si consideri la funzione échange che accetta due parametri formali $a e $b. La funzione scambia il valore di questi due parametri. Pertanto, in caso di chiamata di scambio ($i,$j), il codice chiamante si aspetta che i valori dei due parametri effettivi vengano scambiati. Si tratta quindi di parametri di uscita (vengono modificati). Si scriverà quindi:
3.7. Risultati restituiti da una funzione (exemple_12)
<?php
// risultati restituiti da una funzione
// una funzione può restituire più valori in un array
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
print "res[$i]=$res[$i]\n";
// una funzione può restituire uno pseudo-oggetto
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";
// fine
exit;
// funzione f1
function f1($valeur) {
// restituisce un array ($valeur+1,$aleur+2,$baleur+3)
return array($valeur + 1, $valeur + 2, $valeur + 3);
}
// funzione f2
function f2($valeur) {
// restituisce uno pseudo-oggetto ($valeur+1,$aleur+2,$baleur+3)
$res->res1 = $valeur + 1;
;
$res->res2 = $valeur + 2;
$res->res3 = $valeur + 3;
// restituisce l'oggetto
return $res;
}
?>
Risultati
Commenti
- il programma precedente mostra che una funzione PHP può restituire un insieme di risultati e non uno solo, sotto forma di tabella o di oggetto. Il concetto di oggetto viene spiegato più avanti
- righe 19-22: la funzione f1 restituisce più valori sotto forma di array
- righe 25-33: la funzione f2 restituisce più valori sotto forma di oggetto
3.8. I file di testo (exemple_13)
<?php
// elaborazione sequenziale di un file di testo
// quest'ultimo è un insieme di righe della forma login:pwd:uid:gid:infos:dir:shell
// ogni riga viene inserita in un dizionario nella forma login => uid:gid:infos:dir:shell
// si imposta il nome del file
$INFOS = "infos.txt";
// lo si apre in modalità di creazione
if (!$fic = fopen($INFOS, "w")) {
print "Erreur d'ouverture du fichier $INFOS en écriture\n";
exit;
}
// si genera un contenuto arbitrario
for ($i = 0; $i < 100; $i++)
fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// si chiude il file
fclose($fic);
// lo si sfrutta - fgets mantiene il carattere di fine riga
// questo permette di non recuperare una stringa vuota durante la lettura di una riga vuota
// si apre in modalità di creazione
if (!$fic = fopen($INFOS, "r")) {
print "Erreur d'ouverture du fichier $INFOS en lecture\n";
exit;
}
while ($ligne = fgets($fic, 1000)) {
// si rimuove il carattere di fine riga, se presente
$ligne = cutNewLineChar($ligne);
// si inserisce la riga in un array
$infos = explode(":", $ligne);
// si recupera il login
$login = array_shift($infos);
// si ignora la password
array_shift($infos);
// si crea una voce nel dizionario
$dico[$login] = $infos;
}
// si chiude
fclose($fic);
// utilizzo del dizionario
afficheInfos($dico, "login10");
afficheInfos($dico, "X");
// fine
exit;
// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
// visualizza il valore associato alla chiave nel dizionario $dico se esiste
if (isset($dico[$clé])) {
// il valore esiste - è un array?
$valeur = $dico[$clé];
if (is_array($valeur)) {
print "[$clé," . join(":", $valeur) . "]\n";
} else {
// $valeur non è un array
print "[$clé,$valeur]\n";
}
} else {
// $clé non è una chiave del dizionario $dico
print "la clé [$clé] n'existe pas\n";
}
}
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// si rimuove il carattere di fine riga da $ligne, se presente
$L = strlen($ligne); // lunghezza riga
while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
$ligne = substr($ligne, 0, $L - 1);
$L--;
}
// fine
return($ligne);
}
?>
Il file infos.txt:
login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99
I risultati:
Commenti
- riga 11: fopen(nom_fichier,"w") apre il file nom_fichier in modalità di scrittura (w=write). Se il file non esiste, viene creato. Se esiste, viene svuotato. Se la creazione non va a buon fine, fopen restituisce il valore false. Nell’istruzione if (!$fic = fopen($INFOS, "w")) {…}, sono presenti due operazioni successive: 1) $fic = fopen(..) 2) if( ! $fic) {...}
- riga 18: fputs($fic, $chaîne) scrive chaîne nel file $fic.
- riga 20: fclose($fic) chiude il file $fic.
- riga 25: fopen(nom_fichier,"r") apre il file nom_fichier in lettura (r=read). Se l'apertura non va a buon fine (il file non esiste), fopen restituisce un valore false.
- riga 29: fgets($fic,1000) legge la riga successiva del file entro il limite di 1000 caratteri. Nell’istruzione while ($ligne = fgets($fic, 1000)) {…}, sono presenti due operazioni successive: 1) $ligne = fgets(...) 2) while ( ! $ligne). Dopo che è stato letto l’ultimo carattere del file, la funzione fgets restituisce la stringa vuota e il ciclo while si interrompe.
- riga 31: la funzione fgets legge una riga di testo, compreso il carattere di fine riga. La funzione cutNewLineChar alle righe 70-79 rimuove l’eventuale carattere di fine riga.
- riga 72: la funzione strlen($chaîne) restituisce il numero di caratteri di $chaîne.
- riga 73: la funzione substr($ligne, $position, $taille) restituisce $taille caratteri di $ligne, a partire dal carattere n. $position, dove il primo carattere ha il numero 0. Sui sistemi Windows, il carattere di fine riga è "\r\n". Sui sistemi Unix, è la stringa "\n".
- riga 35: la funzione array_shift($tableau) elimina il primo elemento di $tableau e lo restituisce come risultato.
- riga 37: viene utilizzata la funzione array_shift($tableau), ma il suo risultato viene ignorato
- riga 57: la funzione is_array($variable) restituisce true se $variable è un array, altrimenti restituisce false.
- riga 58: la funzione join fa la stessa cosa della funzione implode già vista