Skip to content
Theory · Arrays · lesson 6 of 8

Nested arrays

A hook in the cloakroom can hold not only a coat but a bag too, and the bag has its own tagged pockets. To get the gloves out, you first find the hook and then the right pocket.

Arrays work the same way: the value of an element can be another array. An array that lies inside another array is called a nested array. This is how you store, for example, a list of users where each one has a name and an age:

PHP
<?php

$users = [
    ['name' => 'Anna', 'age' => 31],
    ['name' => 'Boris', 'age' => 25],
];
echo $users[1]['name'], "\n"; // Boris
$users[0]['age'] = 32;
$users[] = ['name' => 'Vera', 'age' => 19];
echo count($users), ' ', $users[0]['age'], "\n"; // 3 32

Let's go through it line by line:

  1. $users is a list, and each of its elements is the card of one user: an associative array with the keys 'name' and 'age'.
  2. $users[1]['name'] is read in steps: $users[1] is Boris's card, and ['name'] takes the name from it. It prints Boris.
  3. $users[0]['age'] = 32; follows the same path and changes the age right inside Anna's card.
  4. $users[] = ['name' => 'Vera', 'age' => 19]; adds a whole new card to the end of the list.
  5. count($users) counts the cards, there are 3, and Anna's age is now 32.

A long array is handy to write over several lines, one element per line. A comma after the last element is allowed: that way a new line can be added without touching the previous one.

Two kinds of nesting

A list of cards

In $users the first index is the card's number, the second is a field inside it: $users[0]['name']. This shape is used when there is a lot of data of one kind, all with the same fields: users, products, orders.

A card with a list inside

It can be the other way round too: in an associative array, one of the fields is a list. print_r helps you look inside such an array: it prints a nested array with an extra indent.

PHP
$order = ['id' => 7, 'items' => ['tea', 'cake']];
$order['items'][] = 'juice';
print_r($order);
// Array
// (
//     [id] => 7
//     [items] => Array
//         (
//             [0] => tea
//             [1] => cake
//             [2] => juice
//         )
//
// )

Here the first key is a field of the order, the second a number in the list: $order['items'][2] gives 'juice'. The line $order['items'][] = 'juice' adds an element to the nested list the same way $a[] = … adds one to an ordinary list.

Walking with two loops

To visit every field of every card, you need two foreach loops: the outer one goes over the cards, the inner one over a card's pairs. As in the multiplication table from the loops theme, the line is built with .=:

PHP
foreach ($users as $user) {
    $line = '';
    foreach ($user as $field => $value) {
        $line .= $field . '=' . $value . ' ';
    }
    echo $line, "\n";
}
// name=Anna age=32
// name=Boris age=25
// name=Vera age=19

Let's go through the steps:

  1. The outer loop puts a copy of the next card into $user.
  2. $line = '' starts a new line for each card.
  3. The inner loop goes over the card's pairs and appends the key, the = sign and the value to $line.
  4. After the inner loop, echo prints the finished line, and the outer loop takes the next card.

Here the bag picture falls short: in a real cloakroom, people rarely put a bag inside a bag. Arrays, though, nest inside each other to any depth—for example, each user can have a list of orders, and each order a list of products.

Common mistake

A field is read straight from the list, without picking a card first:

PHP
echo $users['name'], "\n"; // ✗
TEXT
Warning: Undefined array key "name"

The keys in $users are the card numbers 0, 1 and 2, while the key 'name' exists only inside each card. PHP gives a warning and prints an empty line. Pick the card first, then the field: $users[0]['name'].

Key points

  • The value of an element can be another array; $users[1]['name'] is read in steps: first the card, then the field.
  • A write along such a path, $users[0]['age'] = 32, changes the value inside the nested array.
  • A nested array is walked with two foreach loops: the outer one over the cards, the inner one over their fields.
  • print_r shows a nested array with indents, and reading a field without picking a card gives Warning: Undefined array key.