Estoy viendo que muchas personas están usando los bucles for con range dentro, así que decidí hacerle un Benchmark para ver que solución es mas eficiente a la hora de haces miles de interacciones.

Haciendo un Loop de 1 000 000 interacciones:

<?php
$start = microtime(true);
for ($i = 0; $i < 1000000; $i++){};
echo 'For with count: ' . (microtime(true) - $start).'s', PHP_EOL;


$start = microtime(true);
foreach (range(0, 1000000) as $i){};
echo 'Foreach with range: ' . (microtime(true) - $start).'s', PHP_EOL;


$start = microtime(true);
foreach (range(0, 1000000) as $i){};

$i = 0;
while ($i < 1000000) {
    $i++;
}
echo 'While: ' . (microtime(true) - $start).'s', PHP_EOL;
?>
//PHP 7.4.0
For with count: 0.0095939636230469s
Foreach with range: 0.031963109970093s
While: 0.039216995239258s

Como vemos aquí esta claro que el ‘For con contador’ es mucho mas rapido que el ‘foreach con range’.

El problema en si esta en que el Range genera primero un array con todos los registros a recorrer, por eso es mucho mas lento que un for normal que solo incrementa el valor y lo ve si llego al final.

En otros lenguajes como Python el utilizar range es mas rapido que For, por en momento en PHP aun no es así.

For Range, podría dar problemas de memoria:

Te recomiendo no utilizar for range en caso vayas a hacer miles de interacciones porque te dará problemas de memoria al generar un array enorme en la memoria.

foreach (range(0, 10000000) as $i){};
//PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 4294967304 bytes) in /vicolinker/for_range.php on line 8

Conclusion:

Podrías utilizar range en caso sea algo pequeño si quieres hacer algo optimizado utiliza for y ademas ahorraras muchísima memoria.