Array in PHP: indicizzati, associativi e multidimensionali (con esempi)
Scritto da Francesco Sganga Categoria: Tutorial Tipo di lettura: 8 min.Array in PHP: indicizzati, associativi e multidimensionali (con esempi)
In PHP gli array sono strutture dati estremamente flessibili che fungono contemporaneamente da liste ordinate, dizionari (mappe chiave/valore) e strutture nidificate. Esistono tre forme principali: array indicizzati (con chiavi numeriche 0, 1, 2...), array associativi (con chiavi stringa, simili a dizionari Python o object JS), e array multidimensionali (array che contengono altri array). PHP non distingue tipologicamente questi tre tipi: sono tutti array, il loro comportamento dipende solo da come li usi.
TL;DR
-
Indicizzato:
[10, 20, 30]— chiavi numeriche automatiche. -
Associativo:
['nome' => 'Marco', 'eta' => 30]— chiavi stringa. -
Multidimensionale:
[['a','b'], ['c','d']]— array dentro array. - Funzioni chiave:
count,array_map,array_filter,array_reduce,in_array,array_keys,array_values,array_merge. - Da PHP 7.1 il destructuring funziona anche con chiavi:
['nome' => $nome] = $utente;. - Per dati strutturati complessi, considera oggetti o DTO invece di array nidificati.
Indice
- Array indicizzati
- Array associativi
- Array multidimensionali
- Iterare un array (foreach, for, while)
- Funzioni essenziali
- Destructuring (assegnazione multipla)
- Spread operator e merge
- Array vs oggetti: quando usare cosa
- Performance e best practice
- FAQ
Array indicizzati {#indicizzati}
L'array più semplice: una lista ordinata con chiavi numeriche automatiche da 0.
$colori = ['rosso', 'verde', 'blu'];
// Equivalente a: array('rosso', 'verde', 'blu')
echo $colori[0]; // rosso
echo $colori[2]; // blu
// Aggiungere elementi
$colori[] = 'giallo'; // appende, chiave 3
array_push($colori, 'viola'); // appende
// Inserire all'inizio
array_unshift($colori, 'nero'); // ora 'nero' è alla chiave 0
// Lunghezza
echo count($colori); // 6
La sintassi corta [ ] è equivalente a array( ) ed è preferita dal 2014 in poi.
Array associativi {#associativi}
Le chiavi sono stringhe (o numeri "speciali") e rappresentano un dizionario.
$utente = [
'id' => 42,
'nome' => 'Marco Rossi',
'email' => '[email protected]',
'attivo' => true,
];
echo $utente['nome']; // Marco Rossi
echo $utente['email']; // [email protected]
// Aggiungere/modificare
$utente['telefono'] = '+39 123 4567890';
$utente['nome'] = 'Marco Bianchi'; // sovrascrive
// Rimuovere
unset($utente['attivo']);
// Verificare esistenza di una chiave
if (isset($utente['email'])) { /* ... */ }
if (array_key_exists('email', $utente)) { /* ... */ }
Differenza tra isset e array_key_exists: isset restituisce false se la chiave esiste ma il valore è null. array_key_exists restituisce true anche con valore null. Per la maggior parte dei casi, isset va benissimo e ha performance migliori.
Accesso sicuro con ?? (null coalescing)
Da PHP 7+, evita errori quando la chiave non esiste:
$nome = $utente['nome'] ?? 'Anonimo';
$telefono = $utente['telefono'] ?? null;
Array multidimensionali {#multidimensionali}
Array che contengono altri array. Pattern molto comune per modellare elenchi di entità.
$utenti = [
['id' => 1, 'nome' => 'Marco', 'eta' => 30],
['id' => 2, 'nome' => 'Lucia', 'eta' => 28],
['id' => 3, 'nome' => 'Giulio', 'eta' => 35],
];
echo $utenti[0]['nome']; // Marco
echo $utenti[2]['eta']; // 35
// Iterare
foreach ($utenti as $utente) {
echo $utente['nome'] . ' ha ' . $utente['eta'] . ' anni' . PHP_EOL;
}
Anche le strutture annidate funzionano senza limiti di profondità:
$catalogo = [
'elettronica' => [
'computer' => ['MacBook', 'ThinkPad', 'Surface'],
'telefoni' => ['iPhone', 'Galaxy', 'Pixel'],
],
'libri' => [
'narrativa' => ['Il nome della rosa', 'Se questo è un uomo'],
'manuali' => ['Programmare con PHP'],
],
];
echo $catalogo['elettronica']['telefoni'][0]; // iPhone
Iterare un array (foreach, for, while) {#iterare}
foreach: la scelta di default
// Solo valori
foreach ($colori as $colore) {
echo $colore . PHP_EOL;
}
// Chiave e valore (per associativi e multidimensionali)
foreach ($utente as $chiave => $valore) {
echo "$chiave: $valore" . PHP_EOL;
}
// Per array di oggetti
foreach ($utenti as $u) {
echo $u['nome'] . PHP_EOL;
}
for (raramente necessario per array)
Utile solo per array indicizzati quando devi controllare l'indice:
for ($i = 0; $i < count($colori); $i++) {
echo "Colore $i: " . $colori[$i] . PHP_EOL;
}
Anti-pattern: chiamare count() nella condizione di un loop. PHP ricalcola la dimensione ogni iterazione. Meglio:
$n = count($colori);
for ($i = 0; $i < $n; $i++) { /* ... */ }
array_walk (modifica in-place)
array_walk($colori, function (&$val, $key) {
$val = strtoupper($val);
});
// $colori ora è ['ROSSO', 'VERDE', 'BLU', ...]
Funzioni essenziali {#funzioni}
PHP ha centinaia di funzioni per gli array. Queste sono quelle che userai ogni giorno.
Trasformare: array_map
Applica una funzione a ogni elemento, restituisce un nuovo array.
$numeri = [1, 2, 3, 4, 5];
$quadrati = array_map(fn($n) => $n ** 2, $numeri);
// [1, 4, 9, 16, 25]
$nomi = array_map(fn($u) => $u['nome'], $utenti);
// ['Marco', 'Lucia', 'Giulio']
Filtrare: array_filter
Tiene solo gli elementi che superano un test.
$pari = array_filter($numeri, fn($n) => $n % 2 === 0);
// [1=>2, 3=>4] attenzione: le chiavi rimangono!
// Reindicizzare se serve
$pari = array_values(array_filter($numeri, fn($n) => $n % 2 === 0));
// [2, 4]
// Filtrare oggetti
$adulti = array_filter($utenti, fn($u) => $u['eta'] >= 30);
Aggregare: array_reduce
Riduce a un singolo valore.
$somma = array_reduce($numeri, fn($acc, $n) => $acc + $n, 0);
// 15
$etaTotale = array_reduce($utenti, fn($acc, $u) => $acc + $u['eta'], 0);
Ricerca: in_array, array_search, array_filter
in_array('verde', $colori); // true / false
array_search('verde', $colori); // chiave (1) o false
// Trovare un oggetto
$marco = array_filter($utenti, fn($u) => $u['nome'] === 'Marco');
$marco = reset($marco); // primo risultato
Estrazione: array_keys, array_values, array_column
array_keys($utente);
// ['id', 'nome', 'email', 'telefono']
array_values($utente);
// [42, 'Marco Bianchi', '...', '...']
// Estrarre una colonna da un array multidimensionale
$nomi = array_column($utenti, 'nome');
// ['Marco', 'Lucia', 'Giulio']
// Indicizzare per id
$utentiPerId = array_column($utenti, null, 'id');
// [1 => [...], 2 => [...], 3 => [...]]
array_column è oro: usalo spesso per trasformare strutture dati.
Ordinamento: sort, usort, asort, ksort
// Ordinamento semplice (in-place)
sort($numeri); // [1, 2, 3, 4, 5]
// Ordinamento con comparatore (oggetti)
usort($utenti, fn($a, $b) => $a['eta'] <=> $b['eta']);
// Più giovani prima
// Mantenere le chiavi
asort($utente); // ordina per valore
ksort($utente); // ordina per chiave
L'operatore <=> (spaceship) restituisce -1, 0, 1 per <, =, >. Indispensabile per usort.
Destructuring (assegnazione multipla) {#destructuring}
Da PHP 7.1 puoi "destrutturare" un array in variabili.
// Indicizzato
[$a, $b, $c] = [1, 2, 3];
// $a=1, $b=2, $c=3
// Saltare elementi
[, , $terzo] = [1, 2, 3];
// $terzo = 3
// Associativo (con chiavi)
['nome' => $nome, 'eta' => $eta] = $utente;
// $nome = 'Marco Bianchi', $eta = 30
// In foreach
foreach ($utenti as ['nome' => $nome, 'eta' => $eta]) {
echo "$nome ha $eta anni" . PHP_EOL;
}
Pattern utilissimo per leggere risultati di funzioni che restituiscono array:
function getCoordinate(): array {
return [42.5, 13.7];
}
[$lat, $lng] = getCoordinate();
Spread operator e merge {#spread}
Da PHP 7.4 lo spread operator ... funziona anche con gli array:
$a = [1, 2, 3];
$b = [4, 5, 6];
$c = [0, ...$a, ...$b, 7];
// [0, 1, 2, 3, 4, 5, 6, 7]
Da PHP 8.1 funziona anche con chiavi stringa:
$nome = ['nome' => 'Marco'];
$contatti = ['email' => '...', 'tel' => '...'];
$utente = [...$nome, ...$contatti, 'attivo' => true];
Equivalente al classico array_merge:
$risultato = array_merge($a, $b);
Differenza: array_merge rinumera le chiavi numeriche; lo spread no.
Array vs oggetti: quando usare cosa {#vs-oggetti}
Gli array associativi tentano la sirena dell'uso "ovunque". Tre regole per evitare il caos:
- Array: collezioni omogenee (lista di nomi, di id, di colori) o dati strutturati temporanei.
- Oggetto/DTO: entità con campi noti e ripetuti (utenti, prodotti, fatture).
- Array di oggetti: collezioni di entità.
Esempio di refactor da array a oggetto:
// Brutto: array nidificato, niente type hint, errori a runtime
function inviaEmail(array $utente, array $messaggio): bool {
// $utente['email'] potrebbe non esistere
}
// Meglio: classe con typed properties (PHP 7.4+) o readonly (PHP 8.2+)
class Utente {
public function __construct(
public readonly int $id,
public readonly string $nome,
public readonly string $email,
) {}
}
function inviaEmail(Utente $utente, Messaggio $msg): bool {
// $utente->email è garantito esistere e essere stringa
}
In Laravel/Symfony si usano spesso DTO (Data Transfer Object) per questo scopo.
Performance e best practice {#performance}
Evita count() dentro a loop
// Lento
for ($i = 0; $i < count($array); $i++) { }
// Veloce
for ($i = 0, $n = count($array); $i < $n; $i++) { }
Verifica chiave: isset vs array_key_exists
isset è 5-10x più veloce, ma restituisce false se il valore è null. Usa array_key_exists solo se devi distinguere "chiave assente" da "chiave con valore null".
Concatenazione: evita array_merge in loop
// Lento (O(n²))
$risultato = [];
foreach ($pagine as $pagina) {
$risultato = array_merge($risultato, $pagina);
}
// Veloce (O(n))
$risultato = [];
foreach ($pagine as $pagina) {
foreach ($pagina as $item) {
$risultato[] = $item;
}
}
// O ancora meglio con spread (PHP 7.4+)
$risultato = array_merge(...$pagine);
Memoria: dati molto grandi
Per dataset di migliaia di righe (es. import CSV), usa Generator invece di accumulare tutto in un array:
function leggiCsv(string $file): Generator {
$fp = fopen($file, 'r');
while ($row = fgetcsv($fp)) {
yield $row; // Una riga alla volta, non tutto in memoria
}
fclose($fp);
}
foreach (leggiCsv('grande.csv') as $row) {
// processa una riga
}
FAQ {#faq}
Qual è la differenza tra [] e array()?
Nessuna, sono sintassi equivalenti. [] è la più recente (PHP 5.4+) e oggi standard di fatto.
Posso usare numeri e stringhe come chiavi nello stesso array? Sì:
$mix = [0 => 'zero', 'uno' => 1, 2 => 'due'];
PHP converte automaticamente chiavi stringa che sembrano numeri ("42" diventa 42).
Gli array in PHP sono passati per valore o per riferimento?
Per valore (PHP fa copia-on-write). Se vuoi modificare un array passato come argomento, usa &:
function aggiungi(array &$arr, $val): void {
$arr[] = $val;
}
Come converto un array in JSON?
json_encode($array) per produrre JSON, json_decode($json, true) per ottenere un array associativo (senza true ottieni un oggetto stdClass).
Posso avere chiavi duplicate? No, ogni chiave deve essere unica. Se ne dichiari due uguali, l'ultima sovrascrive le precedenti.
Differenza tra array_merge e +?
-
array_merge: rinumera chiavi numeriche, sovrascrive chiavi stringa con valore del secondo. -
+: mantiene le chiavi del primo array, aggiunge solo chiavi nuove del secondo.
[0 => 'a', 1 => 'b'] + [0 => 'x', 2 => 'c'];
// Output: [0 => 'a', 1 => 'b', 2 => 'c']
array_merge([0 => 'a', 1 => 'b'], [0 => 'x', 2 => 'c']);
// Output: [0 => 'a', 1 => 'b', 2 => 'x', 3 => 'c']
Esiste un equivalente del Set di JavaScript?
Non nativo, ma simulabile con array associativo (chiave = valore). Da PHP 7.4 puoi usare SplObjectStorage per Set di oggetti o la classe Ds\Set se hai l'estensione PHP Data Structures installata.
Come trovo il valore minimo / massimo di un array?
min($array) e max($array) per scalari. Per oggetti:
$piuGiovane = array_reduce($utenti,
fn($carry, $u) => ($carry === null || $u['eta'] < $carry['eta']) ? $u : $carry);
Risorse
- Documentazione PHP sugli array
- Funzioni array (lista completa)
- Articolo correlato: Variabili e tipi di dato in PHP (in arrivo)
- Articolo correlato: foreach in PHP: tutti i modi per iterare (in arrivo)
Domande sugli array? La community PHP Italia su Telegram risponde dubbi pratici in tempo reale.
preg_match e regex in PHP: guida completa con esempi italiani
JSON in PHP: encode, decode, errori e best practice (2026)
PHP include, require, require_once: differenze e best practice 2026