Corso Web – Lezione PHP – #7 – I cicli indefiniti e la gestione di un file di testo
Argomenti:
- Introduzione
- Il ciclo while in PHP
- L’apertura di un file di testo in PHP
- Lo script PHP
- La prova e conclusioni
- Video della lezione
Introduzione
Nella lezione precedente abbiamo realizzato uno script php in una pagina HTML per visualizzare i numeri compresi in un intervallo [a,b] con a < b attraverso l’uso di una struttura ciclica a ripetizione definita “for”. Il ciclo for che utilizza un contatore per contare il numero delle ripetizione non sempre è utile per la risoluzione di problemi specifici quando il numero delle ripetizioni non è fissato a priori.
Introduciamo la struttura ciclica “while” ripetizione indefinita pre -condizionale, che ripete un blocco di istruzioni “corpo del ciclo” fin quando la condizione è verificata. Esiste anche la ripetizione indefinita post-condizionale che ripete le istruzioni prima e poi verifica la condizione. Se la condizione è verificata esegue un’altra iterazione altrimenti esce dal ciclo.
Il ciclo “while” in PHP
Il ciclo while è strutturato secondo il seguente schema generico:
while (condizione)
{ corpo del ciclo;}
ad esempio il nostro esercizio svolto con il ciclo for con il ciclo while è modificato nella struttura come sotto riportato:
echo "<table border='2'>";
$k=$a;
while ($k<=$b)
{
echo "<tr>";
echo "<td>".$k."</td>";
echo "<td>".($k*2)."</td>";
echo "<td>".($k*10)."</td>";
echo "</td>";
$k++;
}
echo "</table>";
E’ sufficiente sostituire il codice della “lezione 6” con questo e l’esercizio riproduce lo stesso funzionamento previsto nello script precedente.
In questo caso il ciclo while si comporta come un ciclo “for” in quanto è definito un contatore $k che deve avere un intervallo di variazione da $a a $b ovvero i due valori inseriti nella form html.
In questo caso è riprodotto un ciclo “definito” con un ciclo indefinito.
Per completezza è riportato il codice php completo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Esercizio 6 PHP e HTML
</title>
</head>
<body>
<h2>Visualizza i numeri compresi fra a e b </h2>
<h1>Dati:</h1>
<form name="frmsaluta" action="<?php $PHP_SE_LF ?>" method="post">
<table border="1">
<tr>
<td><label for="a">Numero a:</label></td>
<td><input type="number" name="a" id="a" value="Digita il valore" require>
</tr>
<tr>
<td><label for="b">Numero b:</label></td>
<td><input type="number" name="b" id="b" value="Digita il valore" require>
</tr>
<tr>
<td><input type="submit" name="valuta" id="valuta" value="Valuta"></td>
<td><input type="reset" name="cancella" id="cancella" value="Cancella
ati"></td>
</tr>
</table>
</form>
<?php
if ($_SERVER['REQUEST_METHOD']=='POST')
{
$a=$_POST['a'];
$b=$_POST['b'];
if ($a>$b)
{
$tmp=$a;
$a=$b;
$b=$tmp;
}
echo "<table border='2'>";
$k=$a;
while ($k<=$b)
{
echo "<tr>";
echo "<td>".$k."</td>";
echo "<td>".($k*2)."</td>";
echo "<td>".($k*10)."</td>";
echo "</td>";
$k++;
}
echo "</table>";
} ?>
</body>
</html>
L’apertura di un file di testo in PHP
Il ciclo while è molto utile quando occorre leggere dati da un file esterno; in questo caso il nostro file esterno contiene 4 campi per ogni riga “codice prodotto”,”descrizione”,”prezzo” e “quantità”. Ogni valore nel file è sperato da un carattere “;”. Il separatore deve essere scelto fra un carattere che non è un valore ammesso nelle informazioni che sono memorizzate nel file.
La struttura di questo file di testo che è un CSV è mostra a titolo di esempio sotto:
AZ01;Computer;13.5;3
AZ02;Notebook 4k;299.3;5
E’ utile notare che nessun valore compare fra virgolette sarà compito del programmatore attribuire un tipo corretto. In questo caso però il problema vuole mostrare in tabella html i dati riportati nel file. Quindi non ha importanza se il valore del campo è una stringa o un numero in quanto deve essere solo visualizzato.
Per gestire un file di testo occorre utilizzare l’istruzione fopen che prevede come sintassi diverse opzioni così come mostrato:
$nome file logico=fopen(nome file fisico, modalità di apertura);
il nome del flle fisico è il nome del file così come è memorizzato in termini di percorso e nome file sul web server che deve comunque permettere l’accesso mediante la chiamata fopen. A volte tale impostazione è disattivata e occorre andare a modificare il file php.ini di configurazione delle impostazioni PHP sul web server. Non sempre è possibile ma nella stragrande maggiornaza è consentito.
Il nome del file logico rappresenta la variabile riferimento che è associata al file fisico per essere poi utilizzata nello script.
La modalità di accesso al file è discriminata dal un codice “r” sta per lettura, “w” per scrittura, e “a” per aggiunta. Per il nostro esercizio è opportuna la modalità “read” lettura, e quindi per ora nell’ipotesi che il file di dati è nella stessa cartella dello script è possibile omettere anche il percorso completo ove il file è memorizzato. E’ opportuno per motivi di sicurezza a livello di script che i file dati siano sempre all’interno di una sottocartella ove è locato lo script. E’ sconsigliato memorizzare il file in una cartella esterna a quella dove lo script è memorizzato.
Una volta aperto il file la variabile delegata a contenere il nome del file logico contiene il riferimento al file ed è possibile leggere una riga del file con l’istruzione fgets(nome variabile stringa). Questa operazione è fatta all’interno di un ciclo while fin quando non è raggiunta la fine del file che è controllata con la funzione feof(nome file logico).
Il blocco di codice è strutturato come riportato qui sotto:
Lo script PHP
<?php
$fp=fopen("dati.txt","r");
if (!$fp)
{ die("<h2>Non trovo il file nome e/o percorso errato !</h2>"); }
while (!feof($fp))
{ $riga=fgets($fp);
$riga=trim($riga);
$dati=explode(";",$riga);
echo "<tr>";
echo "<td>".$dati[0]."</td>";
echo "<td>".$dati[1]."</td>";
echo "<td>".$dati[2]."</td>";
echo "<td>".$dati[3]."</td>";
echo "</tr>";
}
fclose($fp);
echo "</table>"; ?>
echo “</table>”; ?> Questa porzione di codice include anche due altre caratteristiche: la prima una volta letta la riga che è memorizzata nella variabile $riga è “pulita di spazi esterni” con la funzione trim; la seconda che la riga deve essere poi “esplosa” in un array di 4 elementi nel quale in ogni elemento è presente il valore corretto del cmpo. Questa operazione è svolta con la funzione explode che prende due argomenti il seperatore e la stringa da separare secondo il carattere separatore prescelto in questo caso il “;”:
Alla fine è chiuso il file.
Il codice completo incluso di Csse HTML è:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ciclo While e Do While</title>
</head>
<style>
table{
width: 50%;
border-collapse: collapse;
margin: 20px auto;
font-family: Arial, Helvetica, sans-serif;
}
th, td
{ border: 1px solid #ddd;
padding: 8px;
text-align: center;
}
th
{
background-color: #f4f4f4;
}
tr:nth-child(event)
{
background-color: #f9f9f9;
}
h1
{
text-align:center;
color: beige;
padding: 0.2em;
font-size: 1.4em;
}
</style>
<body>
<table border="1" name="tabella">
<th>Codice Prodotto</th><th>Descrizione</th><th>Prezzo</th><th>Quantità</th>
<?php
$fp=fopen("dati.txt","r");
if (!$fp)
{
die("<h2>Non trovo il file nome e/o percorso errato !</h2>");
}
while (!feof($fp))
{
$riga=fgets($fp);
$riga=trim($riga);
$dati=explode(";",$riga);
echo "<tr>";
echo "<td>".$dati[0]."</td>";
echo "<td>".$dati[1]."</td>";
echo "<td>".$dati[2]."</td>";
echo "<td>".$dati[3]."</td>";
echo "</tr>";
}
fclose($fp);
echo "</table>";
?>
</body>
</html>
La prova e conclusioni
L’esecuzione dello script produce nel browser la seguente visualizzazione della pagina html risultato.

Come è utile notare nella tabella i valori dei campi sono visualizzati secondo il significato che il programmatore conferisce all’interno del file.
Un ulteriore annotazione è possibile in relazione al tipo di struttura dati utilizzata per la memorizzazione che è un file di testo in chiaro, e che se l’utente conosce l’url del file sul web server potrebbe carpire i dati. Un modo migliore + quello di codificare i dati mediante un file binario o inserire i dati all’interno di un database ove comunque è previsto un accesso protetto con nome utente e password.