Skip to main content
    Courses/PHP/Arrays & Collections

    Lesson 7 • Intermediate

    Arrays & Collections 📦

    By the end of this lesson you'll store many values in one variable — ordered lists, key-value records, and nested tables — and reshape them at will with PHP's array functions, the everyday workhorse of real applications.

    What You'll Learn in This Lesson

    • Build indexed, associative, and multidimensional arrays with the [] short syntax
    • Add and remove items with $a[] =, unset, and array_push/pop/shift/unshift
    • Loop over arrays cleanly with foreach (including key => value)
    • Search and inspect arrays with count, in_array, array_keys and array_values
    • Transform data with array_map, array_filter, and array_reduce
    • Sort, merge, join and split arrays — sort/usort/ksort, array_merge, implode/explode, spread ... and list()

    1️⃣ Indexed Arrays — Ordered Lists

    An array is a single variable that holds many values. The simplest kind is an indexed array — an ordered list where PHP labels each slot with a number starting at 0, not 1. You create one with the modern short syntax [ ] (older code uses array(...) — same thing). You read a slot by its index, and you tack a value onto the end with the handy $array[] = ... shortcut, which lets PHP pick the next number for you.

    Creating and reading an indexed array
    <?php
    // An INDEXED array is an ordered list. Keys are numbers, starting at 0.
    $fruits = ["Apple", "Banana", "Cherry"];   // [] is the short array syntax
    
    echo $fruits[0] . "\n";          // Apple   — first item is index 0
    echo $fruits[2] . "\n";          // Cherry  — third item is index 2
    echo count($fruits) . "\n";      // 3       — how many items are in the array
    
    // Add to the END with $array[] = ... (PHP picks the next number for you)
    $fruits[] = "Date";               // now index 3 holds "Date"
    echo count($fruits) . "\n";      // 4
    
    // implode() joins every item into one string with a separator between them
    echo implode(", ", $fruits) . "\n";   // Apple, Banana, Cherry, Date
    ?>
    Output
    Apple
    Cherry
    3
    4
    Apple, Banana, Cherry, Date
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    2️⃣ Associative Arrays — Key → Value

    When position isn't meaningful but a label is, use an associative array. Instead of numbers, you choose your own keys — usually strings — and pair each with a value using the => arrow (read it as "points to"). This is how PHP models a record: a user, a config setting, a row from a database. You look values up by key, and assigning to a new key adds it while assigning to an existing key overwrites it.

    Building a record with string keys
    <?php
    // An ASSOCIATIVE array maps your OWN keys (usually strings) to values.
    // Syntax: ['key' => 'value']  — the => arrow reads as "points to".
    $person = [
        "name" => "Alice",
        "age"  => 28,
        "city" => "London",
    ];
    
    echo $person["name"] . "\n";     // Alice  — look a value up BY its key
    echo $person["age"] . "\n";      // 28
    
    // Add or update by assigning to a key
    $person["role"] = "Developer";    // new key
    $person["age"]  = 29;             // overwrites the old value
    
    // Inside "double quotes" wrap an array lookup in { } to print it cleanly
    echo "{$person['name']} is {$person['age']}, role {$person['role']}\n";
    // Alice is 29, role Developer
    ?>
    Output
    Alice
    28
    Alice is 29, role Developer
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    Notice the {$person['name']} trick: inside a double-quoted string, wrapping an array lookup in curly braces lets PHP drop the value in cleanly. Without the braces, "$person['name']" confuses the parser.

    3️⃣ Multidimensional Arrays & foreach

    Because an array's values can themselves be arrays, you can build tables and nested structures — a list of records, a grid, JSON-shaped data. To walk through any array, reach for foreach: it hands you each element in turn without you tracking an index. To reach a nested value, stack the brackets: outer position, then inner key.

    A list of records, looped with foreach
    <?php
    // A MULTIDIMENSIONAL array is an array whose values are themselves arrays.
    // Here each row is an associative array describing one student.
    $students = [
        ["name" => "Alice", "grade" => 95],
        ["name" => "Bob",   "grade" => 87],
        ["name" => "Cara",  "grade" => 92],
    ];
    
    // foreach walks the list one row at a time; $s is the current inner array
    foreach ($students as $s) {
        // Reach into a nested value with TWO sets of brackets
        echo "{$s['name']}: {$s['grade']}\n";
    }
    
    // Reach a single nested value directly: outer index, then inner key
    echo "First student: {$students[0]['name']}\n";   // Alice
    ?>
    Output
    Alice: 95
    Bob: 87
    Cara: 92
    First student: Alice
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    4️⃣ Adding & Removing Items

    Arrays are not fixed in size — you grow and shrink them as the program runs. Append with the $a[] = shortcut or array_push (which can add several at once); add to the front with array_unshift. Remove and capture the last item with array_pop or the first with array_shift. To delete one specific element by key, use unset — but note it leaves a gap in the numbering rather than renumbering.

    Growing and shrinking an array
    <?php
    $queue = ["Alice", "Bob"];
    
    // --- ADDING ---
    $queue[] = "Cara";                // append one item (shortest way)
    array_push($queue, "Dan", "Eve"); // push one OR MORE onto the end
    array_unshift($queue, "Zoe");     // add to the FRONT (everything shifts right)
    echo implode(", ", $queue) . "\n";
    // Zoe, Alice, Bob, Cara, Dan, Eve
    
    // --- REMOVING ---
    $last  = array_pop($queue);       // remove & RETURN the last item -> "Eve"
    $first = array_shift($queue);     // remove & RETURN the first item -> "Zoe"
    echo "Popped $last, shifted $first\n";
    
    // unset() deletes a specific key (note: it does NOT renumber the rest)
    unset($queue[1]);                 // removes "Bob"; indexes now 0, 2, 3...
    echo implode(", ", $queue) . "\n";   // Alice, Cara, Dan
    ?>
    Output
    Zoe, Alice, Bob, Cara, Dan, Eve
    Popped Eve, shifted Zoe
    Alice, Cara, Dan
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    5️⃣ Transforming Data — map, filter, reduce

    The real power of PHP arrays is its library of built-in functions. Three are worth learning by heart. array_map applies a function to every element and returns a new array. array_filter keeps only the elements your test returns true for. array_reduce boils the whole array down to a single value (a sum, a max, a joined string). Watch the argument orderarray_map(fn, array) but array_filter(array, fn). Alongside them, in_array, array_keys, array_values, and the string pair implode/explode cover most everyday needs.

    The everyday array toolkit
    <?php
    $nums = [5, 2, 8, 1, 9, 3];
    
    // array_map: TRANSFORM every item. Order: (callback, array). Returns a NEW array.
    $doubled = array_map(fn($n) => $n * 2, $nums);
    echo implode(", ", $doubled) . "\n";     // 10, 4, 16, 2, 18, 6
    
    // array_filter: KEEP items where the callback is true. Order: (array, callback).
    $evens = array_filter($nums, fn($n) => $n % 2 === 0);
    echo implode(", ", $evens) . "\n";       // 8 (only the even numbers survive)
    
    // array_reduce: BOIL the array down to ONE value. Order: (array, callback, start).
    $total = array_reduce($nums, fn($carry, $n) => $carry + $n, 0);
    echo "Sum: $total\n";                     // Sum: 28
    
    // Membership & keys/values
    echo in_array(8, $nums) ? "has 8\n" : "no 8\n";   // has 8
    $prices = ["pen" => 2, "pad" => 5];
    echo implode(", ", array_keys($prices)) . "\n";    // pen, pad
    echo implode(", ", array_values($prices)) . "\n";  // 2, 5
    
    // implode joins to a string; explode splits a string back into an array
    $csv = implode("-", [2024, 6, 16]);        // "2024-6-16"
    $parts = explode("-", $csv);               // ["2024", "6", "16"]
    echo "$csv -> {$parts[1]}\n";             // 2024-6-16 -> 6
    ?>
    Output
    10, 4, 16, 2, 18, 6
    8
    Sum: 28
    has 8
    pen, pad
    2, 5
    2024-6-16 -> 6
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    Now you try. The script below is almost complete — fill in each ___ using the 👉 hint, then run it and check it against the Output panel.

    🎯 Your turn: build and join an array
    <?php
    // 🎯 YOUR TURN — fill in each blank marked ___ , then run it.
    
    // 1) Make an indexed array of three colours
    $colours = ___;            // 👉 e.g.  ["red", "green", "blue"]
    
    // 2) Append "yellow" to the END using the [] shortcut
    $colours___ = "yellow";    // 👉 put [] right after $colours
    
    // 3) Print how many colours there are now
    echo ___($colours) . "\n"; // 👉 the function that counts items
    
    // 4) Join them into one line separated by ", "
    echo ___(", ", $colours) . "\n";   // 👉 the function that joins to a string
    
    // ✅ Expected output:
    //    4
    //    red, green, blue, yellow
    ?>
    Output
    4
    red, green, blue, yellow
    Fill the four ___ blanks (a list, the [] append, then count and implode), then run it.

    6️⃣ Sorting, Merging & Unpacking

    sort reorders an indexed list ascending — but it renumbers the keys, so on an associative array it would throw your labels away. For keyed data use asort (by value) or ksort (by key); for a custom rule use usort with a comparison function. To combine arrays, use array_merge or the newer spread operator ...; and list() destructuring — written as [$x, $y] = [...] — unpacks an array straight into separate variables.

    Sorting, spread, and destructuring
    <?php
    // sort() reorders an INDEXED array in place (ascending) and renumbers keys.
    $nums = [5, 2, 8, 1];
    sort($nums);
    echo implode(", ", $nums) . "\n";         // 1, 2, 5, 8
    
    // For ASSOCIATIVE arrays use asort()/ksort() so keys stay attached.
    $scores = ["Bob" => 87, "Alice" => 95, "Cara" => 92];
    asort($scores);                            // sort by VALUE, keep keys
    echo implode(", ", array_keys($scores)) . "\n";   // Bob, Cara, Alice
    ksort($scores);                            // sort by KEY (alphabetical)
    echo implode(", ", array_keys($scores)) . "\n";   // Alice, Bob, Cara
    
    // usort() sorts with YOUR rule. Return negative/zero/positive to order pairs.
    $people = [["n" => "Al", "age" => 30], ["n" => "Bo", "age" => 22]];
    usort($people, fn($a, $b) => $a["age"] - $b["age"]);  // youngest first
    echo "{$people[0]['n']} is youngest\n";   // Bo is youngest
    
    // Spread ... and list() destructuring
    $more = [4, 5];
    $all  = [1, 2, 3, ...$more];                // spread merges arrays: 1,2,3,4,5
    echo implode(", ", $all) . "\n";          // 1, 2, 3, 4, 5
    [$x, $y] = [10, 20];                        // list() unpacks into variables
    echo "$x and $y\n";                        // 10 and 20
    ?>
    Output
    1, 2, 5, 8
    Bob, Cara, Alice
    Alice, Bob, Cara
    Bo is youngest
    1, 2, 3, 4, 5
    10 and 20
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    One more. Build a small contact card as an associative array, then loop it with foreach ($arr as $key => $value), which hands you both halves of each pair.

    🎯 Your turn: an associative contact card
    <?php
    // 🎯 YOUR TURN — build a contact card with an associative array.
    
    // 1) Create an associative array with keys "name" and "email"
    $contact = [
        "name"  => ___,        // 👉 a name in "double quotes"
        "email" => ___,        // 👉 an email in "double quotes"
    ];
    
    // 2) Add a "city" key AFTER creating the array
    $contact[___] = "Paris";   // 👉 the key name, in quotes
    
    // 3) Loop over every key => value pair and print it
    foreach ($contact as $key => $value) {
        echo "$key: $value\n";
    }
    
    // ✅ Expected output (example):
    //    name: Sam
    //    email: sam@mail.com
    //    city: Paris
    ?>
    Output
    name: Sam
    email: sam@mail.com
    city: Paris
    Fill the ___ blanks with a name, an email, and the "city" key. The loop prints each pair on its own line.

    Common Errors (and the fix)

    • "Warning: Undefined array key 'email'" — you read a key that doesn't exist (a typo, or it was never set). PHP returns null and warns. Guard it with isset($a['email']) or supply a default with the null-coalescing operator: $a['email'] ?? 'none'.
    • array_map and array_filter take their arguments in opposite orders — it's array_map(fn, $arr) but array_filter($arr, fn). Swap them by mistake and you'll get a "TypeError: argument must be callable". When in doubt, the array comes second in map and first in filter/reduce.
    • Your keys vanished after sorting an associative arraysort() (and rsort()) reindex from 0, discarding string keys. To keep key→value pairs intact, use asort()/arsort() to sort by value, or ksort() to sort by key.
    • "PHP Parse error: syntax error, unexpected '=>'" — you used the => arrow outside an array, or mixed it up with assignment =. The arrow only links a key to a value inside array brackets or a foreach.

    Pro Tips

    • 💡 Reach for map/filter/reduce before writing a loop. They state your intent ("transform", "keep", "total") and avoid off-by-one bugs from manual indexing.
    • 💡 Use $a['key'] ?? $default whenever a key might be missing — it's the clean, warning-free way to read optional data.
    • 💡 Pick one style per array. A purely indexed list or a purely associative record reads far clearer than one that mixes numeric and string keys.

    📋 Quick Reference — PHP Arrays

    Syntax / FunctionExampleWhat It Does
    [ ]$a = [1, 2, 3];Create an array (short syntax)
    =>["name" => "Al"]Map a key to a value
    $a[] =$a[] = 4;Append to the end
    unset()unset($a[1]);Delete one key (no renumber)
    count()count($a)Number of items
    in_array()in_array(2, $a)Is a value present? (bool)
    array_map()array_map($fn, $a)Transform every element
    array_filter()array_filter($a, $fn)Keep matching elements
    array_reduce()array_reduce($a, $fn, 0)Boil down to one value
    sort() / usort()usort($a, $cmp)Reorder (renumbers keys)
    asort() / ksort()ksort($a)Sort, keeping keys
    array_merge()array_merge($a, $b)Combine arrays
    implode() / explode()implode(",", $a)Array ↔ string
    ... / [ ] =[...$a]; [$x] = $a;Spread / list() unpack

    Frequently Asked Questions

    Q: What is the difference between an indexed and an associative array?

    An indexed array uses automatic integer keys starting at 0 — it's an ordered list like ["a", "b", "c"]. An associative array uses keys you choose yourself, almost always strings, written with the => arrow: ["name" => "Alice"]. Under the hood PHP has only one array type — an ordered map — so a single array can even mix numeric and string keys, but for clarity you should pick one style per array.

    Q: Why does in_array() give a warning but array_search() returns a key?

    They answer different questions. in_array(needle, haystack) returns a boolean — true or false — telling you whether a value exists. array_search(needle, haystack) returns the key of the first match, or false if nothing matches. Watch out: a match at index 0 returns 0, which is falsy, so test the result with === false (strict comparison) rather than a plain if when the key could legitimately be 0.

    Q: Why are the arguments to array_map and array_filter in a different order?

    It is one of PHP's oldest inconsistencies. array_map(callback, array) takes the callback first, while array_filter(array, callback) takes the array first. There is no logic to it — you simply have to remember it (or let your editor remind you). array_reduce(array, callback, initial) follows array_filter's order and adds a starting value. Mixing the order up is one of the most common PHP array bugs.

    Q: When should I use sort() versus asort() or usort()?

    Use sort() for a plain indexed list when you only care about the order of the values — it discards the old keys and renumbers from 0, so never use it on an associative array you want to keep keyed. Use asort()/arsort() to sort by value while keeping keys attached, and ksort()/krsort() to sort by key. Use usort() (and uasort/uksort) when you need a custom rule, such as sorting objects by a property: your callback returns a negative, zero, or positive number to order each pair.

    Q: What does the spread operator (...) do with arrays?

    Inside an array literal, ...$other unpacks every element of $other into the new array, which is a clean way to merge: [1, 2, ...$more] gives a single flat array. In a function definition, function sum(...$nums) collects all extra arguments into one array. Since PHP 8.1 the spread operator also preserves string keys when merging associative arrays, behaving much like array_merge().

    Mini-Challenge: Top Scorers

    No code is filled in this time — just a brief and an outline. Write it yourself, run it on onecompiler.com/php or your own machine, then check your result against the expected output in the comments. This combines array_filter, usort, foreach and array_reduce — the real toolkit.

    🎯 Mini-Challenge: filter, sort, and average a class
    <?php
    // 🎯 MINI-CHALLENGE: Top scorers report.
    // No code is filled in — work from the steps, then run it.
    //
    // Starter data (copy this line in):
    //   $students = [
    //       ["name" => "Alice", "grade" => 95],
    //       ["name" => "Bob",   "grade" => 62],
    //       ["name" => "Cara",  "grade" => 88],
    //       ["name" => "Dan",   "grade" => 74],
    //   ];
    //
    // 1. Use array_filter to keep only students with grade >= 75 (the "passers").
    // 2. Use usort to order the passers by grade, HIGHEST first.
    //    (Tip: return $b['grade'] - $a['grade'] to sort descending.)
    // 3. foreach over the result and echo "  <name>: <grade>" on its own line.
    // 4. Use array_reduce (or a count + sum) to print the average of ALL grades.
    //
    // ✅ Expected output:
    //    Alice: 95
    //    Cara: 88
    //    Average: 79.75
    
    // your code here
    ?>
    Filter the passers (grade ≥ 75), sort them highest-first with usort, print each, then print the average of all grades.

    🎉 Lesson Complete!

    • Indexed arrays are ordered lists keyed by numbers from 0; associative arrays map your own keys with =>
    • ✅ Arrays nest: a multidimensional array holds arrays, and foreach walks any of them
    • ✅ Grow and shrink with $a[] =, array_push/pop/shift/unshift, and unset
    • array_map, array_filter, and array_reduce transform, keep, and combine data (mind the argument order)
    • sort renumbers keys; use asort/ksort/usort to keep or customise order
    • implode/explode, spread ..., and list() move data between arrays, strings, and variables
    • Next lesson: File Handling — read and write files on the server

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service

    Install LearnCodingFast

    Learn faster with the app on your home screen.