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.

References