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
-
Find the headliner. Use
array_find()to get the act on themainstage at hour 23. Print their name. -
Find the problem slot. Use
array_find_key()to find the array index of the act that is not confirmed yet. Print the index. -
Genre check. Use
array_any()to check whether any act plays theelectronicgenre. Printyesorno. -
Readiness check. Use
array_all()to verify whether all acts are confirmed. Printready to go!orstill waiting on acts. -
First and last. Sort a copy of the lineup by
hour(useusort()), then usearray_first()andarray_last()to print who opens and who closes the festival. -
๐ Bonus. Confirm Four Tet (set
confirmedtotruein the original$lineupentry you found in challenge 2), then assert thatarray_all()now returnstrue. -
๐ Bonus bonus. What does
array_find()return when nothing matches? What aboutarray_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()?
<?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],
];
// 1. Find the headliner (PHP 8.4)
$headliner = array_find($lineup, fn($act) => $act['stage'] === 'main' && $act['hour'] === 23);
echo $headliner['name'] . PHP_EOL; // Arctic Monkeys
// 2. Find the unconfirmed act's index (PHP 8.4)
$pendingKey = array_find_key($lineup, fn($act) => !$act['confirmed']);
echo $pendingKey . PHP_EOL; // 2
// 3. Any electronic acts? (PHP 8.4)
$hasElectronic = array_any($lineup, fn($act) => $act['genre'] === 'electronic');
echo $hasElectronic ? 'yes' : 'no'; // yes
echo PHP_EOL;
// 4. All confirmed? (PHP 8.4)
$allConfirmed = array_all($lineup, fn($act) => $act['confirmed']);
echo $allConfirmed ? 'ready to go!' : 'still waiting on acts'; // still waiting on acts
echo PHP_EOL;
// 5. Opening and closing acts (PHP 8.5)
$sorted = $lineup;
usort($sorted, fn($a, $b) => $a['hour'] <=> $b['hour']);
$opener = array_first($sorted);
$closer = array_last($sorted);
echo $opener['name'] . ' opens, ' . $closer['name'] . ' closes' . PHP_EOL;
// Wet Leg opens, Arctic Monkeys closes
// Bonus: confirm Four Tet and re-check
$lineup[$pendingKey]['confirmed'] = true;
echo array_all($lineup, fn($act) => $act['confirmed']) ? 'ready to go!' : 'still waiting on acts';
echo PHP_EOL; // ready to go!
๐งช 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.