Loops are simple, but a few mistakes show up again and again. Learn to spot them early.
1. The infinite loop
A loop that never reaches its stop condition runs until PHP’s max_execution_time ends the script.
<?php
$i = 1;
while ($i <= 5) {
echo $i;
// forgot $i++ so the condition is always true
}
PHP stops a web request after the time limit (30 seconds by default). On the command line, there is no limit, so press Ctrl+C. Before running a new loop, say out loud what makes it stop.
2. Off-by-one
<?php
$items = ["a", "b", "c"];
for ($i = 0; $i <= count($items); $i++) {
echo $items[$i] ?? "(nothing)";
}
abc(nothing)
The loop ran one time too many. <= count() should be < count(). (Without ??, you would see a “Undefined array key 3” warning.)
3. Changing an array while you loop through it
Adding or removing items of the array you are looping over leads to confusing results. Build a new array instead.
<?php
$numbers = [1, 2, 3, 4, 5, 6];
$odd = [];
foreach ($numbers as $n) {
if ($n % 2 !== 0) {
$odd[] = $n;
}
}
echo implode(", ", $odd);
1, 3, 5
4. Forgetting to unset a reference
<?php
$list = [1, 2, 3];
foreach ($list as &$value) {
// ...
}
// forgot unset($value)
foreach ($list as $value) {
// the second loop writes into the last item!
}
print_r($list);
Array
(
[0] => 1
[1] => 2
[2] => 2
)
The last item should be 3, but it became 2. The first loop left $value pointing at the last item. The second loop then wrote each value into it. Fix it with unset($value); after the first loop.
5. Doing the same work in every round
// Slow: count() is called again and again
for ($i = 0; $i < count($bigArray); $i++) { /* ... */ }
// Better: compute it once
$total = count($bigArray);
for ($i = 0; $i < $total; $i++) { /* ... */ }
For arrays, PHP makes count() fast, but the idea matters for anything slower, such as a database query. Never run a database query inside a loop if one query can fetch everything. See Avoiding Repeated Work.
6. Using the loop variable afterwards
After a for or foreach, the variable keeps its last value. That can confuse readers and cause bugs.
<?php
foreach ([10, 20, 30] as $n) {}
echo $n;
30