PHP 8.4 PHP 8.5

๐ŸŽต Exercise 3 โ€” Festival Lineup

๐Ÿ“– The setup

You're building a festival planner. You have a lineup of acts across multiple stages, and programme managers keep asking you questions like "is there anyone still unconfirmed?", "who headlines the main stage?", "which act opens the day?".

In the old days you'd loop over everything. PHP 8.4 and 8.5 added six new functions that let you answer these questions in a single expression โ€” no loops, no helper variables.

๐Ÿงฑ Starter code

festival.php โ€” starter

<?php

$lineup = [
    ['name' => 'Wet Leg',        'genre' => 'indie',      'stage' => 'second', 'hour' => 17, 'confirmed' => true],
    ['name' => 'Fontaines D.C.', 'genre' => 'rock',       'stage' => 'second', 'hour' => 19, 'confirmed' => true],
    ['name' => 'Four Tet',       'genre' => 'electronic', 'stage' => 'tent',   'hour' => 20, 'confirmed' => false],
    ['name' => 'Bicep',          'genre' => 'electronic', 'stage' => 'tent',   'hour' => 22, 'confirmed' => true],
    ['name' => 'Peggy Gou',      'genre' => 'electronic', 'stage' => 'main',   'hour' => 22, 'confirmed' => true],
    ['name' => 'Arctic Monkeys', 'genre' => 'rock',       'stage' => 'main',   'hour' => 23, 'confirmed' => true],
];

// Challenge 1 โ€” find the headliner (main stage, hour 23)
// Old way:
$headliner = null;
foreach ($lineup as $act) {
    if ($act['stage'] === 'main' && $act['hour'] === 23) {
        $headliner = $act;
        break;
    }
}
echo $headliner['name'] . PHP_EOL; // Arctic Monkeys
// TODO: replace with array_find()


// Challenge 2 โ€” find the index of the unconfirmed act
// Old way:
$pendingKey = null;
foreach ($lineup as $key => $act) {
    if (!$act['confirmed']) {
        $pendingKey = $key;
        break;
    }
}
echo $pendingKey . PHP_EOL; // 2
// TODO: replace with array_find_key()


// Challenge 3 โ€” does any act play electronic?
// Old way:
$hasElectronic = false;
foreach ($lineup as $act) {
    if ($act['genre'] === 'electronic') {
        $hasElectronic = true;
        break;
    }
}
echo $hasElectronic ? 'yes' : 'no';
echo PHP_EOL; // yes
// TODO: replace with array_any()


// Challenge 4 โ€” are all acts confirmed?
// Old way:
$allConfirmed = true;
foreach ($lineup as $act) {
    if (!$act['confirmed']) {
        $allConfirmed = false;
        break;
    }
}
echo $allConfirmed ? 'ready to go!' : 'still waiting on acts';
echo PHP_EOL; // still waiting on acts
// TODO: replace with array_all()


// Challenge 5 โ€” who opens and who closes?
// Old way:
$sorted = $lineup;
usort($sorted, fn($a, $b) => $a['hour'] <=> $b['hour']);
$opener = reset($sorted); // first element
$closer = end($sorted);   // last element
echo $opener['name'] . ' opens, ' . $closer['name'] . ' closes' . PHP_EOL;
// Wet Leg opens, Arctic Monkeys closes
// TODO: replace reset() / end() with array_first() / array_last()

๐ŸŽฏ Your challenges

  1. Find the headliner. Use array_find() to get the act on the main stage at hour 23. Print their name.
  2. Find the problem slot. Use array_find_key() to find the array index of the act that is not confirmed yet. Print the index.
  3. Genre check. Use array_any() to check whether any act plays the electronic genre. Print yes or no.
  4. Readiness check. Use array_all() to verify whether all acts are confirmed. Print ready to go! or still waiting on acts.
  5. First and last. Sort a copy of the lineup by hour (use usort()), then use array_first() and array_last() to print who opens and who closes the festival.
  6. ๐ŸŽ Bonus. Confirm Four Tet (set confirmed to true in the original $lineup entry you found in challenge 2), then assert that array_all() now returns true.
  7. ๐ŸŽ Bonus bonus. What does array_find() return when nothing matches? What about array_all() on an empty array? Write a small test to find out and explain the result.
๐Ÿ’ก Hint โ€” signatures at a glance
// PHP 8.4
array_find(array $array, callable $callback): mixed        // first value where callback returns true, or null
array_find_key(array $array, callable $callback): mixed    // key of that value, or null
array_any(array $array, callable $callback): bool          // true if ANY element matches
array_all(array $array, callable $callback): bool          // true if ALL elements match (vacuously true for [])

// PHP 8.5
array_first(array $array): mixed                           // first value, or null for empty array
array_last(array $array): mixed                            // last value, or null for empty array

// usage pattern:
$match = array_find($lineup, fn($act) => $act['stage'] === 'main');
$key   = array_find_key($lineup, fn($act) => $act['hour'] > 22);
โœ… Show one possible solution

Answer both questions correctly to unlock the solution.

1. What does array_find() return?

2. What is the difference between array_any() and array_all()?

๐Ÿงช Think about it: array_find() returns null on no match โ€” but what if a valid element in your array is null? How would you tell the difference? Try array_find_key() instead and check for null there.
Copied to clipboard!