for
Learn the PHP for loop: initialization, condition and increment expressions, array iteration, nested loops, infinite loops, and avoiding off-by-one bugs.
The PHP for Loop
for is PHP's counter-controlled loop. You use it when you know — or can compute — exactly how many times a block of code should run, such as iterating from 0 to count($array) - 1, counting down, or stepping by an interval. This page covers the three parts of the loop header, how each one runs, how to iterate arrays, infinite and nested loops, the alternative endfor syntax, and the off-by-one mistakes that catch most beginners.
If you instead want to walk over every element of an array or object without managing an index, foreach is usually the better tool. For a loop that runs until a condition becomes false, see while. A high-level comparison of all loop types lives in PHP Loops.
Syntax
for (initialization; condition; increment) {
// code to be executed on each pass
}The header has three expressions, separated by semicolons:
| Expression | When it runs | Typical use |
|---|---|---|
initialization | Once, before the loop starts | Set up a counter, e.g. $i = 0 |
condition | Before every iteration | Loop continues while it is truthy |
increment | After every iteration | Advance the counter, e.g. $i++ |
The execution order is: run initialization, evaluate condition; if it is true, run the body, then run increment, then re-evaluate condition, and so on. The moment condition evaluates to false, the loop stops and the body does not run that final time.
A first example
<?php
for ($i = 1; $i <= 5; $i++) {
echo $i . PHP_EOL;
}
// Output:
// 1
// 2
// 3
// 4
// 5The counter starts at 1. After printing 5, $i++ makes it 6, 6 <= 5 is false, and the loop ends — so it runs exactly five times.
Iterating over an array
A classic use of for is indexing into an array. Cache count() in a variable (or use the increment slot) so PHP does not recount the array on every pass:
<?php
$colors = ["red", "green", "blue"];
for ($i = 0, $n = count($colors); $i < $n; $i++) {
echo $colors[$i] . PHP_EOL;
}
// Output:
// red
// green
// blueNote that array indexes start at 0, so the last valid index is count($colors) - 1. The condition uses < (not <=) precisely because of this — using <= here would read one element past the end. When you only need the values and not the index, prefer foreach, which avoids this whole class of off-by-one error.
Counting down and stepping
The increment expression is just code — it can decrement or jump by any amount:
<?php
// Count down
for ($i = 5; $i >= 1; $i--) {
echo $i . " ";
}
echo PHP_EOL;
// Output: 5 4 3 2 1
// Step by 2 (even numbers only)
for ($i = 0; $i <= 10; $i += 2) {
echo $i . " ";
}
// Output: 0 2 4 6 8 10Multiple expressions and empty slots
Each of the three slots can hold several comma-separated expressions, and any slot may be left empty. The semicolons are required even when the slots are blank:
<?php
// Two counters moving toward each other
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
echo "$i-$j" . PHP_EOL;
}
// Output:
// 0-10
// 1-9
// 2-8
// 3-7
// 4-6If the condition slot is empty it is treated as true, which gives you an infinite loop. You then control the exit from inside the body with break:
<?php
$i = 0;
for (;;) {
if ($i >= 3) {
break;
}
echo $i . PHP_EOL;
$i++;
}
// Output:
// 0
// 1
// 2Use continue to skip the rest of the current iteration and jump straight to the increment step.
Nested loops
Placing one for inside another lets you work with grids, tables, and multiplication-style patterns. Use distinct counter names for each level:
<?php
for ($row = 1; $row <= 3; $row++) {
for ($col = 1; $col <= 3; $col++) {
echo ($row * $col) . "\t";
}
echo PHP_EOL;
}
// Output:
// 1 2 3
// 2 4 6
// 3 6 9The inner loop completes all of its iterations for each single pass of the outer loop.
Alternative endfor syntax
PHP offers a colon/endfor form that is handy when mixing loops with HTML in templates, because it avoids stray closing braces:
<?php for ($i = 1; $i <= 3; $i++): ?>
<p>Item <?= $i ?></p>
<?php endfor; ?>This renders three <p> paragraphs. The same alternative syntax exists for foreach/endforeach.
Common pitfalls
- Off-by-one errors.
$i <= count($arr)reads one slot past the end (an undefined index warning); use$i < count($arr). - Modifying the array length inside the loop. If the body adds or removes elements, a cached
count()can become stale — re-check, or switch toforeach. - Accidental infinite loops. Forgetting the increment, or comparing in the wrong direction (e.g.
$i--with$i < 10), means the condition never becomes false. - Floating-point counters. Stepping by
0.1accumulates rounding error and may overshoot the boundary; loop with integers and divide inside the body instead.
When to use for
Reach for for when the iteration count is known or computed up front and you genuinely need the index (countdowns, fixed repetition, stepping, building tables). When you simply want every element of a collection, foreach is cleaner and safer. When the number of repetitions depends on a condition that changes inside the loop, use while or do...while.