Um array multidimensional é um array cujos elementos são arrays. Você o lê com um par de colchetes por nível: $grid[1][2] é a linha 1, coluna 2, e $users[0]['name'] é o nome no primeiro registro.
O segundo formato, uma lista de registros com campos nomeados, é o que você mais vai encontrar: é o que uma consulta ao banco, uma resposta JSON decodificada ou um arquivo CSV processado normalmente entregam. Cada registro é um array associativo.
Criar arrays aninhados
O aninhamento pode ir tão fundo quanto você precisar, e os níveis podem misturar chaves numéricas e string. Um array de configuração é um exemplo comum: seções com nome, cada uma com configurações ou listas.
Adicionar linhas e valores aninhados
$rows[] = [...] acrescenta uma linha inteira. $arr['key'][] = $value acrescenta dentro de uma lista aninhada, e o PHP cria o array interno na primeira vez, então agrupar valores não exige preparação.
Percorrer um array multidimensional
Use um foreach por nível. Para uma lista de registros, um loop costuma bastar, porque você lê os campos pelo nome. Para uma grade, o loop interno percorre as células de cada linha.
Montar uma tabela HTML a partir de um array
Um array de linhas vira diretamente uma tabela HTML: as chaves da primeira linha viram o cabeçalho, e cada linha vira um <tr>. Rode e a aba Page mostra a tabela renderizada; mude um valor ou adicione uma linha e rode de novo.
A forma foreach (...): ... endforeach; é o mesmo loop escrito para templates, para que o HTML continue legível.
Pegar uma coluna de todas as linhas
array_column() extrai um campo de cada linha para uma lista simples. Passe um terceiro argumento para indexar o resultado por outro campo, o que transforma uma lista de registros numa tabela de consulta.
Ordenar linhas por um campo
usort() ordena as linhas com uma função de comparação. O operador spaceship <=> retorna -1, 0 ou 1, exatamente o que o usort() espera. Troque $a e $b para ordenar em ordem decrescente.
count($players, COUNT_RECURSIVE) conta as 3 linhas mais os 6 campos dentro delas, e é por isso que imprime 9.
Erro comum: ler uma chave profunda que pode não existir
Ler $config['cache']['ttl'] quando não há chave cache imprime Warning: Undefined array key "cache", seguido de Warning: Trying to access array offset on null para o próximo nível. O operador ?? verifica a cadeia inteira de uma vez e nunca avisa, então é o jeito seguro de ler valores aninhados opcionais.
Perguntas frequentes
Como acesso um valor num array multidimensional em PHP?
Adicione um par de colchetes por nível: $matrix[1][0] é a linha 1, coluna 0, e $users[0]['email'] é o e-mail do primeiro usuário. Cada colchete lê do array retornado pelo anterior.
Como percorro um array multidimensional em PHP?
Aninhe um foreach por nível: foreach ($rows as $row) { foreach ($row as $key => $value) { ... } }. Para uma lista de registros, normalmente basta um loop e ler os campos pelo nome: $row['name'].
Como adiciono um elemento a um array multidimensional?
Acrescente uma linha inteira com $rows[] = ['name' => 'Linus', 'age' => 54];, ou acrescente dentro de um array aninhado com $groups['admins'][] = 'Grace';. O PHP cria o array interno se a chave ainda não existir.
Como crio um array 2D cheio de zeros em PHP?
Aninhe duas chamadas a array_fill(): $grid = array_fill(0, 3, array_fill(0, 4, 0)); dá 3 linhas de 4 zeros. Cada linha é uma cópia própria, então $grid[0][0] = 5; altera só a primeira linha.