Foundation · 45 MINUTES · VERSION 1
Count tasks by status with PHP arrays
Build a task report with safe fallback behavior and explain its complexity.
Reviewed 23 Oct 2026Your setup may differ. Windows, Ubuntu, and optional tool bundles →
What you will learn
- Read a PHP array containing task records.
- Count tasks by status using a loop.
- Handle a missing or unsupported status safely.
Before you start
Use a supported PHP installation and a terminal on Windows or Ubuntu/Linux. Complete PHP values and strict comparisons first. This lesson introduces the foreach loop below. Run php --version to check the interpreter. This example was checked with PHP 8.4.26. It does not need Laravel, MySQL, Apache, Nginx, or a Composer package.
On Windows you may use standalone PHP, a compatible PHP version in Laragon/XAMPP, or another setup. Open its terminal or make its PHP executable available on PATH. On Ubuntu, use an installed supported PHP CLI. Check Get-Command php in PowerShell, where php in Command Prompt, or command -v php in Ubuntu to identify the executable you are actually running. A bundle's PHP version may differ from another terminal's version.
Theory in simple English
An array holds multiple values. An indexed array can represent a list of tasks. Each task is an associative array: it has named keys such as title and status. A separate associative array holds the counters.
Start each counter at zero. Visit each task once. Increase the matching counter. This is useful for reports and dashboards. Unknown data must not quietly create new report categories.
foreach ($tasks as $task) visits each value in the task list. The second loop, foreach ($counts as $status => $count), reads both each key and its value. ++ adds one to a counter. An if branch runs only when its condition is true; else handles the other case. The && operator requires both conditions and stops when the first is false. This prevents a non-string status from reaching the allowed-status check.
Worked example
Create task_summary.php:
<?php
declare(strict_types=1);
$tasks = [
['title' => 'Fix login', 'status' => 'done'],
['title' => 'Write tests', 'status' => 'todo'],
['title' => 'Review code', 'status' => 'done'],
['title' => 'Update notes', 'status' => 'in_progress'],
];
$counts = ['todo' => 0, 'in_progress' => 0, 'done' => 0, 'unknown' => 0];
foreach ($tasks as $task) {
$status = $task['status'] ?? null;
if (is_string($status) && in_array($status, ['todo', 'in_progress', 'done'], true)) {
$counts[$status]++;
} else {
$counts['unknown']++;
}
}
foreach ($counts as $status => $count) {
echo $status . ': ' . $count . PHP_EOL;
}
Run php task_summary.php. Expected output:
todo: 1
in_progress: 1
done: 2
unknown: 0
?? null gives a fallback when status is missing or null. is_string checks the type. The true argument in in_array enables strict comparison. The code increments only an approved category.
For n tasks, the counting loop takes O(n) time. The counters have four keys, so their additional space is O(1). The input array itself still uses memory proportional to its size.
Guided lab
- Run the original example. Check all four output lines.
- Add another
todotask. Expecttodo: 2. - Add status
blocked. Expect the unknown counter to increase. - Add a task without a
statuskey. It should also count as unknown. - Try an empty array. Expect all counters to be zero.
- Use a non-string status. It should count as unknown.
The example assumes every task is an array. A later validation exercise can reject other row types.
Independent exercise
Before looking at hints, predict the four counters for five task arrays: one todo, two done, one missing status, and one with status blocked. Run your input through the counting code and compare expected and actual output. Then add status in_progress to a sixth task and verify only that counter increases. Keep the original task arrays unchanged. In the next functions lesson, separate calculation from display; you do not need to know function syntax to finish this exercise.
Common mistakes
- Initializing counters inside the task loop resets previous counts.
- Using an unchecked status as an array key can create unwanted categories.
- Directly reading a missing key can produce a warning.
- Printing inside calculation logic makes the result harder to reuse in tests or an API.
Self-check — not graded
- Why do counters start before the loop?
- What happens when the status key is missing?
- How does the counting time change if the input doubles?
Interview practice
“How would you count a million tasks already stored in MySQL?” Explain database aggregation with GROUP BY, filtering, measurement, and why loading all rows into PHP may be unnecessary. Add caching only after considering freshness and actual query performance.
English practice and glossary
- Array: a collection of values.
- Key: a name or index used to find a value.
- Counter: a number that increases as matching items are found.
- Fallback: a value or behavior used when expected data is missing.
Say: “This report counts tasks by status. I keep unsupported statuses in the unknown category. I checked the empty-input case.” Write your own short explanation.
Next step
Next, learn functions, return values, input validation, and useful errors. Later, move this report's calculation into a function and compare it with an SQL aggregate and the Python version.
Reveal exercise hints and self-check answers
Exercise result: todo 1, in_progress 0, done 2, unknown 2. After adding the sixth task: todo 1, in_progress 1, done 2, unknown 2. Initialize counters before the loop and check that the input still contains all original values. The total of the counters equals the number of task rows under this example's assumption that each row is an array.
- They must retain their values as the loop moves to the next task.
- It becomes null through the fallback and increments unknown.
- Work grows roughly in proportion to the input size: O(n).