While, do.....while, break, for, foreach
Passiamo ora al dettaglio dell'utilizzo delle strutture di controllo iterative.
Il ciclo while è la forma di ciclo più semplice tra quelle possibili in PHP.
Si comporta come la sua controparte nel linguaggio C.
La forma di base di un ciclo while è la seguente:
while (espressione) istruzione
Il significato di un ciclo while è semplice. Istruisce l'interprete PHP perchè esegua l'istruzione (o le istruzioni) in esso racchiuse, ripetutamente, fintanto che l'espressione contenuta nella clausola while ha valore TRUE.
Il valore dell espressione viene verificato ogni volta che il ciclo si ripete (iterazione), così che anche se il valore dell'espressione cambia durante l esecuzione dell'istruzione, il ciclo non termina fino all'iterazione successiva.
Ovviamente, se l'espressione nella clausola while ha valore FALSE dall'inizio, l'istruzione racchiusa nel blocco non verrà eseguita nemmeno una volta.
Come nel caso della struttura di controllo if, si possono raggruppare più istruzioni nello medesimo ciclo while racchiudendo le istruzioni in parentesi graffa, oppure utilizzando la sintassi alternativa:
while (espressione): istruzione ... endwhile;
Gli esempi seguenti sono identici e entrambi visualizzano i numeri da 1 a 10:
/* esempio 1 */
$i = 1;
while ($i <= 10) {
print $i++;
/* Il valore visualizzato è il valore della variabile $i prima dell incremento (post-incremento) */
}
/* esempio 2 */
$i = 1;
while ($i <= 10):
print $i;
$i++;
endwhile;
Il ciclo do..while è simile al ciclo while, con l'unica differenza che il valore dell espressione viene controllato alla fine di ogni iterazione anziché all inizio.
La differenza più importante rispetto a while è che la prima iterazione di un blocco do..while verrà sempre eseguita (il valore dell espressione viene controllato alla fine del ciclo), mentre non sarà necessariamente eseguito in un ciclo while (il valore dell espressione viene controllato all inizio del ciclo, e se tale valore è FALSE dall' inizio, l'esecuzione del ciclo termina immediatamente).
È ammessa una sola sintassi per il ciclo do..while:
$i = 0;
do
{
print $i;
} while ($i>0);
Il ciclo precedente verrà eseguito un unica volta, dal momento che alla prima iterazione, quando si controlla l espressione, il suo valore sarà FALSE ($i non è maggiore di 0) e il ciclo di esecuzioni, termina.
Chi ha utilizzato il linguaggio C conosce probabilmente un altro modo di utilizzare il ciclo do..while, che permette di terminare l esecuzione delle istruzioni durante l'esecuzione stessa, utilizzando do..while(0), e usando l istruzione break.
Il codice che segue esemplifica questa possibilità:
do
{
if ($i < 5)
{ print "i non è abbastanza grande";
break; }
$i *= $factor;
if ($i < $minimum_limit)
{ break;
}
print "i è ok";
...processa i...
} while(0);
Il ciclo for è il ciclo più complesso tra quelli disponibili in PHP.
Si comporta come la sua controparte nel linguaggio C.
La sintassi di un ciclo for è:
for (espressione1; espressione2; espressione3) istruzione
Il valore della prima espressione (espressione1) viene verificato (eseguito) una sola volta incondizionatamente all'inizio del ciclo.
Ad ogni iterazione, si controlla il valore di espressione2.
Se è TRUE, il ciclo prosegue e viene eseguita l'istruzione (o le istruzioni) contenuta nel blocco; se è FALSE, l'esecuzione del ciclo termina.
Al termine di ogni iterazione, si verifica (si esegue) il valore di espressione3.
Le due espressioni possono anche non essere presenti. Se non esiste espressione2 significa che il ciclo deve essere eseguito indefinitamente (PHP considera implicitamente che il suo valore è TRUE, come in C).
Questa possibilità in fondo non è utile come può sembrare perché obbliga a terminare il ciclo utilizzando l'istruzione break invece di utilizzare le espressioni booleane del ciclo for .
Si considerino gli esempi seguenti.
In ciascun caso si visualizzeranno i numeri da 1 a 10:
/* esempio 1 */
for ($i = 1; $i <= 10; $i++) { print $i; }
/* esempio 2 */
for ($i = 1;;$i++) {
if ($i > 10) {
break;
}
print $i;
}
/* esempio 3 */
$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i; $i++;
}
/* esempio 4 */
for ($i = 1; $i <= 10; print $i, $i++) ;
Naturalmente il primo esempio sembra il migliore (o forse il quarto), ma l 'uso del ciclo for senza espressioni può essere utile in molti casi.
PHP offre una sintassi alternativa (con i "punto e virgola") per i cicli for.
for (espressione1; espressione2; espressione3): istruzione; ...; endfor;
Alcuni linguaggi permettono l'uso della struttura di controllo foreach per attraversare un array o una tabella hash.
PHP 3 non permette l'uso di tale ciclo mentre PHP 4 si .
In PHP 3 è possibile combinare while con la funzione list() e each() per ottenere la stessa funzionalità.
PHP 4 (non PHP 3) permette l'uso della struttura di controllo foreach, alla stessa maniera del linguaggio Perl e altri.
Ciò semplicemente fornisce un facile metodo per attraversare un array.
Esistono due possibili notazioni sintattiche; la seconda è un utile estensione della prima:
foreach(array_expression as $value) istruzione
foreach(array_expression as $key => $value) istruzione
La prima attraversa l'array dato da array_expression.
Ad ogni ciclo, si assegna il valore dell'elemento corrente a $value e il puntatore interno avanza di una posizione (in modo tale che al ciclo successivo l' elemento corrente sarà il successivo elemento dell array).
La seconda esegue lo stesso ciclo con la differenza che il valore dell indice corrente viene assegnato ad ogni ciclo, alla variabile $key.
Nota: All'inizio dell esecuzione di un ciclo foreach il puntatore interno viene automaticamente posizionato nella prima posizione.
Questo significa che non è necessario utilizzare la funzione reset() prima di un ciclo foreach.
Nota: È importante notare che foreach() opera su una copia dell'array, non sull'array stesso, pertanto il puntatore dell array originale non viene modificato come accade utilizzando la funzione each() e le modifiche agli elementi dell array non appaiono nell array originale.
Nota: foreach() non offre la possibilità di annullare la generazione di messaggi d'errore utilizzando il carattere @ .
Avete probabilmente notato che i due cicli seguenti sono identici da un punto di vista funzionale:
reset ($arr);
while (list(, $value) = each ($arr)) {
echo "Valore: $value
\n";
}
foreach ($arr as $value) {
echo "Valore: $value\n";
}
Allo stesso modo i due cicli seguenti sono identici:
reset ($arr);
while (list($key, $value) = each ($arr)) {
echo "Chiave: $key; Valore: $value\n";
}
foreach ($arr as $key => $value) {
echo "Chiave: $key; Valore: $value\n";
}
Di seguito, altri esempi per mostrare possibili utilizzi:
/* esempio 1 foreach: solo il valore */
$a = array (1, 2, 3, 17);
foreach ($a as $v) {
print "Valore corrente di \$a: $v.\n";
}
/* esempio 2 foreach: valore (con la chiave stampata) */
$a = array (1, 2, 3, 17);
$i = 0;
/* solo per un proposito illustrativo */
foreach($a as $v) {
print "\$a[$i] => $v.\n";
$i++;
}
/* esempio 3 foreach: chiave e valore */
$a = array ( "uno" => 1, "due" => 2, "tre" => 3, "diciassette" => 17 );
foreach($a as $k => $v) {
print "\$a[$k] => $v.\n";
}
/* esempio 4 foreach: array multidimensionali */
$a[0][0] = "a"; $a[0][1] = "b"; $a[1][0] = "y"; $a[1][1] = "z";
foreach($a as $v1) {
foreach ($v1 as $v2) { print "$v2\n";
}
}
/* esempio 5 foreach: array dinamici */
foreach(array(1, 2, 3, 4, 5) as $v) {
print "$v\n";
}
break termina l'esecuzione di una struttura for, foreach while, do..while o switch.
break accetta un argomento opzionale che definisce, nel caso di cicli annidati, il livello del ciclo che è da interrompere.
$arr = array ( uno , due , tre , quattro , stop , cinque );
while (list (,$val) = each ($arr)) {
if ($val == stop ) {
break;
/* Qui si può anche usare break 1; . */
}
echo "$val\n";
}
/* Uso dell argomento opzionale. */
$i = 0;
while (++$i) {
switch ($i) {
case 5: echo "At 5\n";
break 1; /* Interrompe solo switch.*/
case10: echo "At 10; quitting\n";
break 2; /* Interrompe switch e while. */
default: break;
}
}
continue si utilizza per interrompere l'esecuzione del ciclo corrente e continuare con l'esecuzione all inizio del ciclo successivo.
continue accetta un argomento numerico opzionale che definisce, nel caso di cicli annidati, il
numero di cicli da interrompere e da cui iniziare l'esecuzione dell iterazione
successiva.
while (list ($key, $value) = each ($arr)) {
if (!($key % 2)) {
//salta i dispari
continue;
}
do_something_odd ($value);
}
$i = 0;
while ($i++ < 5) {
echo "Esterno<br>\n";
while (1) {
echo " Centrale<br>\n";
while (1) {
echo " Interno<br>\n";
continue 3;
}
echo "Questo non sarà mai stampato.<br>\n";
}
echo "Nemmeno questo.<br>\n";
}