for ($i = 0; $i < 5; $i++) { ... } executa o bloco um número fixo de vezes. As três partes são o início ($i = 0, roda uma vez), a condição ($i < 5, verificada antes de cada volta) e o passo ($i++, roda depois de cada volta). O loop termina assim que a condição é falsa.
$i continua existindo depois do loop e guarda o valor que tornou a condição falsa (6). O PHP não tem escopo de bloco para variáveis de loop.
Percorrer um array pelo índice
Para uma lista com chaves 0, 1, 2 ..., o contador também serve de índice. Guarde o count() numa variável antes, para que ele não seja chamado de novo a cada volta.
A primeira parte pode ter várias expressões separadas por vírgulas, e é assim que $n = count($fruits) é definido uma vez. Quando você só precisa de cada valor (e não dos vizinhos), o foreach é mais curto e também funciona em arrays cujas chaves não vão de 0 a n - 1.
Contagem regressiva e passos maiores que 1
O passo pode ser qualquer expressão: $i-- para contar para trás, $i += 2 para um número sim e outro não, $i *= 2 para potências de dois.
range('a', 'h') monta o array ['a', 'b', ... 'h']. Com range(1, 10) e foreach você tem a mesma contagem de um laço for, ao custo de montar o array inteiro antes.
break e continue
break encerra o loop na hora. continue pula o resto da volta atual e vai para o passo e a próxima verificação da condição.
O segundo loop tem a condição vazia, o que significa "sempre verdadeiro", então ele roda até o break. Em loops aninhados, break 2 e continue 2 agem sobre o loop externo, como mostra o próximo exemplo.
Laços for aninhados: uma tabuada
Um loop dentro de outro executa o loop interno por completo a cada volta do externo. Aqui a saída é HTML, então a aba Page mostra uma tabela de verdade.
Mude $size para 12 e rode de novo. A forma for (...): e endfor; é a sintaxe alternativa que mantém os loops legíveis entre tags HTML. A mesma tabela montada como texto puro, e com break 2 para encerrar os dois loops:
Erros comuns: um a mais e o loop infinito
Os dois bugs clássicos do for: usar <= com count() lê um elemento depois do fim, o que o PHP informa como Warning: Undefined array key 3 e trata como null; e um passo que nunca move o contador em direção ao fim ($i-- quando você queria $i++) mantém a condição verdadeira para sempre.
Para loops cujo tamanho você não sabe de antemão, como ler até o fim de um arquivo, um laço while se encaixa melhor.
Perguntas frequentes
Como percorro um array com índice no PHP?
Para uma lista com chaves 0, 1, 2 use for ($i = 0; $i < count($arr); $i++) { echo $arr[$i]; }. Na maior parte do código, foreach ($arr as $i => $value) é mais simples, dá o mesmo índice e também funciona quando as chaves não vão de 0 a n menos 1.
Como saio de um laço for no PHP?
break; sai do loop na hora. Em loops aninhados, break 2; sai do loop interno e do que está em volta dele. continue; pula o resto da volta atual e segue para a próxima.
Como faço uma contagem regressiva com for no PHP?
Comece alto, compare com >= e decremente: for ($i = 10; $i >= 1; $i--) { echo $i; }. Para passos diferentes de um, mude a terceira parte, por exemplo $i += 2 ou $i -= 5.
Quando devo usar for em vez de foreach no PHP?
Use for quando você conta algo (repetir 5 vezes, números de 1 a 100, um elemento sim e outro não) ou precisa do elemento seguinte ou anterior pelo índice. Use foreach para visitar cada elemento de um array, principalmente arrays associativos, em que não há índice numérico.