Menu

Ciclo foreach in PHP: chiave e valore, indice e riferimento

foreach ($array as $value) visita ogni elemento di un array, e foreach ($array as $key => $value) ti dà anche la chiave. Copre come ottenere l'indice, modificare i valori per riferimento e la trappola di unset(), break e continue, array annidati, list() in foreach e la costruzione di HTML.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

foreach ($array as $value) esegue il blocco una volta per ogni elemento, con $value impostato all'elemento corrente. Per avere anche la chiave, scrivi foreach ($array as $key => $value).

foreach funziona su qualsiasi array, qualunque siano le chiavi, e non devi mai gestire un contatore né controllare una lunghezza. È il ciclo che scriverai più spesso in PHP.

Scorrere chiavi e valori

In $key => $value i nomi li scegli tu: $name => $age, $id => $user, $k => $v. Su una lista le chiavi sono le posizioni 0, 1, 2. Su un array associativo sono le chiavi stringa che hai definito.

L'ultimo ciclo mostra un dettaglio che sorprende: una chiave stringa che sembra un numero intero, come "1", viene memorizzata come l'intero 1. "01" non è un intero in forma canonica, quindi resta una stringa.

Ottenere l'indice in foreach

Su una lista la chiave è l'indice, quindi foreach ($items as $i => $item) è tutto ciò che serve. Su un array associativo non c'è una posizione numerica, quindi tieni un contatore. Per trattare in modo diverso il primo o l'ultimo elemento, confronta la chiave con array_key_first() o array_key_last().

L'ultimo ciclo stampa una virgola tra i nomi ma non dopo l'ultimo. Per quel compito preciso implode(', ', array_keys($scores)) è più breve; il controllo con array_key_last() serve quando l'ultimo passaggio richiede una logica diversa, non solo un separatore diverso.

Modificare i valori dell'array in foreach (per riferimento)

$value è una copia. Assegnarle un valore non cambia nulla nell'array. Per modificare l'array, scorri per riferimento con &$value oppure riscrivi tramite la chiave.

Funzionano entrambi. La versione con la chiave non lascia stato nascosto dopo il ciclo, ed è per questo che molti team la preferiscono. Per costruire un nuovo array invece di modificarne uno, array_map() è un'altra opzione.

Una domanda collegata: cosa succede se aggiungi elementi durante il ciclo? Un foreach normale scorre l'array com'era all'inizio del ciclo, quindi $prices[] = ... al suo interno non crea passaggi in più. Un ciclo per riferimento scorre l'array reale e visita anche i nuovi elementi.

La trappola di unset() con foreach per riferimento

Dopo foreach ($arr as &$v), la variabile $v è ancora un riferimento all'ultimo elemento dell'array. Se poi riusi il nome $v in un ciclo normale, ogni passaggio scrive in quell'ultimo elemento. Eseguilo e guarda l'ultima voce:

Il secondo ciclo assegna a $letters[2] prima A, poi B, poi il valore dell'ultimo elemento stesso, e all'ultimo passaggio quella posizione contiene già B. La soluzione è una riga: metti unset($v); subito dopo ogni foreach per riferimento.

break e continue in foreach

break esce dal ciclo, continue passa all'elemento successivo. Uno schema comune è la ricerca: scorri finché non trovi ciò che ti serve, poi break così il resto dell'array non viene controllato.

Nei cicli annidati, break 2 esce dal ciclo interno e da quello che lo contiene, e continue 2 passa al passaggio successivo del ciclo esterno.

Array annidati e foreach con list()

Le righe di dati sono array dentro un array. Scorri le righe e poi ogni riga, oppure estrai i campi direttamente nella riga del foreach con la destrutturazione: [$a, $b] per le liste, ['key' => $var] per le righe associative. list($a, $b) è la grafia più vecchia di [$a, $b].

La pagina sulla destrutturazione approfondisce la sintassi [...] =, compresi gli elementi saltati e gli schemi annidati.

Costruire una lista o una tabella HTML con foreach

In un template, la forma con i due punti foreach (...): con endforeach; mantiene il ciclo leggibile tra i tag. Questo blocco costruisce una tabella, e le intestazioni delle colonne sono link: cliccane una nella scheda Page e lo stesso script viene eseguito di nuovo con $_GET['sort'] impostato, quindi le righe tornano in un nuovo ordine.

Due abitudini da copiare da questo blocco: il valore sort preso dall'URL viene confrontato con un elenco di colonne consentite prima di essere usato, e ogni valore stampato nell'HTML che potrebbe contenere testo dell'utente passa per htmlspecialchars().

foreach su null, un array vuoto o un oggetto

Un array vuoto va bene: il corpo non viene mai eseguito. null, una stringa o un numero no: PHP stampa un warning e salta il ciclo. Per $tags = null; foreach ($tags as $tag) stampa:

Warning: foreach() argument must be of type array|object, null given in /var/www/html/index.php on line 4

Succede soprattutto con dati che a volte mancano, come un campo facoltativo in un JSON decodificato. Ripiega su un array vuoto con ??:

foreach ($data['tags'] ?? [] as $tag) {
    echo $tag;
}

L'object in quel messaggio è reale: foreach su un oggetto visita le sue proprietà visibili dal punto in cui gira il ciclo (fuori dalla classe, quelle pubbliche), con il nome della proprietà come chiave. Le classi che implementano Iterator o IteratorAggregate, e i generatori, decidono da sé cosa vede un foreach.

foreach vs for vs array_map

UsaQuando
foreachVuoi ogni elemento, con o senza la sua chiave. Funziona su qualsiasi array, lista o associativo.
forConti (da 1 a 100, un elemento sì e uno no) o ti servono i vicini tramite indice ($a[$i - 1]). Vedi il ciclo for.
array_map()Costruisci un nuovo array trasformando ogni elemento, spesso in una riga con fn.
array_filter()Tieni solo gli elementi che superano un test.

Un modo rapido per decidere: se il corpo del ciclo calcola solo un nuovo valore per elemento, array_map(fn($x) => $x * 2, $a) lo dice in una riga. Se ha effetti collaterali (stampare, salvare, contare più cose insieme) o richiede break, scrivi il foreach.

Domande frequenti

Come ottengo chiave e valore in un ciclo foreach PHP?

Usa la forma con =>: foreach ($array as $key => $value) { echo "$key: $value"; }. Su una lista semplice la chiave è l'indice (0, 1, 2); su un array associativo è la chiave stringa, come 'name'.

Come ottengo l'indice in un ciclo foreach PHP?

Per una lista, la chiave è già l'indice: foreach ($items as $i => $item). Per un array associativo, tieni un tuo contatore: imposta $i = 0; prima del ciclo e $i++ alla fine di ogni passaggio. array_key_first() e array_key_last() ti dicono quale chiave è la prima o l'ultima.

Come modifico i valori di un array dentro foreach in PHP?

Scorri per riferimento con &: foreach ($prices as &$price) { $price *= 2; } unset($price);. Oppure scrivi tramite la chiave: foreach ($prices as $key => $price) { $prices[$key] = $price * 2; }. Un semplice $price = ... modifica solo una copia.

Perché foreach per riferimento in PHP duplica l'ultimo elemento?

Dopo foreach ($arr as &$v), $v è ancora un riferimento all'ultimo elemento. Un secondo foreach ($arr as $v) scrive allora ogni valore in quell'ultima posizione, che finisce per ripetere il penultimo valore. Chiama unset($v); subito dopo il ciclo per riferimento.

Come esco da un ciclo foreach in PHP?

break; ferma subito il ciclo e continue; passa all'elemento successivo. Nei cicli annidati, break 2; esce sia dal ciclo interno sia da quello esterno.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA