ForeachInvariants
warning on by default quick-fixGroup: Control flow · PhpStorm name: ForeachInvariantsInspection
Two loop shapes that are really array iterations in disguise:
- a counter-based
forthat walks0 … count($a)and reads$a[$i]; - a
while (list($k, $v) = each($a))loop (each()is slow, deprecated in PHP 7.2 and removed in PHP 8). Both are clearer (and faster) asforeach.
Example
php
<?php
function render(array $rows, $cap) {
$total = count($rows);
for ($n = 0; $n < $total; $n++) {
print $rows[$n];
echo $rows[$n]->title, " ({$rows[$n]}) ";
$label = strtoupper($rows[$n]);
$alias = &$rows[$n];
if ($rows[$n] instanceof Stringable) {}
}
for ($n = 0; count($rows) > $n; ++$n) {
$rows[$n][1] = 'x';
echo $rows[$n][2];
}
while (list($slot, $entry) = each($rows)) {
echo $entry;
}
for ($n = 0; $n < $cap; $n++) { echo $rows[$n]; } // E5: parameter
for ($n = 1; $n < count($rows); $n++) { echo $rows[$n]; } // E2
while (list($slot, $entry) = each($rows)) { unset($rows[$slot]); } // E7
}php
<?php
function render(array $rows, $cap) {
foreach ($rows as $n => $nValue) {
print $rows[$n];
echo $nValue->title, " ($nValue) ";
$label = strtoupper($nValue);
$alias = &$rows[$n];
if ($nValue instanceof Stringable) {}
}
foreach ($rows as $n => $nValue) {
$rows[$n][1] = 'x';
echo $nValue[2];
}
foreach ($rows as $entry) {
echo $entry;
}
for ($n = 0; $n < $cap; $n++) { echo $rows[$n]; } // E5: parameter
for ($n = 1; $n < count($rows); $n++) { echo $rows[$n]; } // E2
while (list($slot, $entry) = each($rows)) { unset($rows[$slot]); } // E7
}Reported:
- line 4: Iterate with foreach instead of a counter loop.
- line 11: Iterate with foreach instead of a counter loop.
- line 15: Replace the each() loop with foreach.
Configure
In custos.json:
json
{
"rules": {
"ForeachInvariants": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file), either of:
php
// @custos-ignore ForeachInvariants
/**
* @noinspection ForeachInvariantsInspection
*/