For Loop Over Array
ID |
php.foreach_for_arrays |
Severity |
info |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Php |
Tags |
code_smell, readability |
Description
Reports an index-based for loop that walks an array from 0 up to its element count, for
example for ($i = 0; $i < count($arr); $i++). Iterating an array this way is clearer and
safer when written as foreach ($arr as $value).
Rationale
A for loop that exists only to step an index from zero to the array length carries three
moving parts — initialisation, bound and increment — each of which is an opportunity for an
off-by-one error or an accidental mutation of the index. foreach removes all of them: it
yields each element (and optionally its key) directly, cannot run past the end of the array,
and reads as the iteration it actually is. The rule is intentionally header-only: it fires
when the condition compares the control variable with < or ⇐ against an array count
(written inline or hoisted into a variable on the line just above the loop) and the update is
a unit increment ($i` or `$i) of that same variable. Non-unit steps, descending loops
and fixed numeric bounds are left alone because foreach cannot express them.
<?php
for ($i = 0; $i < count($values); $i++) { // FLAW — index loop over an array
echo $values[$i];
}
$n = count($values);
for ($i = 0; $i < $n; $i++) { // FLAW — count hoisted just above the loop
echo $values[$i];
}
foreach ($values as $value) { // OK — direct iteration
echo $value;
}
for ($i = 0; $i < count($values); $i += 2) { // OK — non-unit step, foreach cannot replace it
echo $values[$i];
}
Remediation
Rewrite the loop as foreach ($array as $value), or foreach ($array as $key ⇒ $value) when
the index is needed. Reserve index-based for loops for cases that genuinely need a numeric
step, a partial range, or a non-unit increment.