Um laço de repetição é uma estrutura que manda o computador executar o mesmo bloco de código várias vezes, enquanto uma condição continuar verdadeira. Em PHP, os dois laços que você vai usar no dia a dia são o while e o for. A regra prática para escolher é simples: use while quando você não sabe quantas repetições vão acontecer, e use for quando você já sabe o número de voltas antes de o laço começar.
Essa é a parte da lógica em que o iniciante finalmente sente que o computador está trabalhando para ele. Até aqui, cada linha escrita executava uma vez. Com laço, três linhas de código fazem mil operações. É também o ponto onde aparecem os primeiros travamentos de verdade: o programa que roda para sempre, o contador que para uma volta antes ou depois do esperado, o total que sai zerado.
Este guia mostra os dois laços com exemplos que rodam de verdade, com a saída exata de cada um. Se você ainda não está firme em if e else em PHP, vale passar por lá antes: todo laço depende de uma condição, e é a mesma condição do if.
O que acontece por dentro de um laço
Um laço tem sempre três ingredientes, mesmo quando eles não estão escritos de forma óbvia:
- Um ponto de partida — normalmente uma variável que começa em zero ou em um.
- Uma condição de parada — a pergunta que o PHP refaz antes de cada volta. Enquanto a resposta for verdadeira, o bloco roda de novo.
- Uma mudança dentro do bloco — alguma coisa precisa mudar a cada volta, senão a condição nunca deixa de ser verdadeira.
Se você entender esses três ingredientes, os dois laços deixam de ser assunto separado: for é só um while com os três ingredientes escritos na mesma linha.
while: repetir enquanto a condição valer
O while pergunta antes de cada volta: "a condição ainda é verdadeira?". Se for, executa o bloco e volta a perguntar. Se não for, pula o bloco inteiro e segue a vida. Uma contagem de 1 até 10 fica assim:
<?php
$contador = 1;
while ($contador <= 10) {
echo $contador . "\n";
$contador = $contador + 1;
}
Saída:
1
2
3
4
5
6
7
8
9
10
Repare na ordem das coisas. A variável $contador nasce fora do laço, valendo 1. A condição $contador <= 10 é testada antes da primeira volta. Dentro do bloco, além de imprimir, a linha $contador = $contador + 1 empurra a variável para a próxima volta. Quando $contador chega a 11, a condição fica falsa e o laço termina — por isso o programa imprime até 10 e não até 11.
Uma dúvida comum: $contador = $contador + 1 parece uma equação impossível na matemática, mas em programação o sinal de igual não compara, ele guarda. Leia como "o novo valor de $contador é o valor antigo mais um". Existe um atalho para isso, $contador++, que faz exatamente a mesma coisa e você vai ver bastante por aí.
Acumulador: somando valores a cada volta
O padrão mais útil de laço para iniciante é o acumulador: uma variável que começa em zero e vai crescendo dentro do bloco. É assim que se soma uma lista de compras, uma folha de pagamento ou as notas de uma turma.
<?php
$precos = [12.50, 3.90, 25.90, 8.00];
$total = 0;
$posicao = 0;
while ($posicao < count($precos)) {
$total = $total + $precos[$posicao];
$posicao = $posicao + 1;
}
echo 'Total da compra: R$ ' . number_format($total, 2, ',', '.') . "\n";
echo 'Itens: ' . count($precos) . "\n";
Saída:
Total da compra: R$ 50,30
Itens: 4
Três detalhes que valem ouro aqui. Primeiro: $total = 0 tem que estar fora do laço — se estiver dentro, o total zera a cada volta e o programa termina mostrando só o preço do último item. Segundo: a contagem de posições em um array começa em 0, então $precos[0] é o primeiro item e a condição usa < (menor), não <=. Terceiro: number_format com os argumentos 2, ',', '.' é o que faz o número sair no formato brasileiro, com vírgula nos centavos.
O mesmo padrão serve para descontar em vez de somar. Este exemplo tira parcelas de R$ 120,00 de um saldo de R$ 500,00 enquanto ainda der para pagar uma parcela inteira:
<?php
$saldo = 500;
$parcela = 120;
$mes = 1;
while ($saldo >= $parcela) {
$saldo = $saldo - $parcela;
echo 'Mês ' . $mes . ' - sobrou R$ ' . number_format($saldo, 2, ',', '.') . "\n";
$mes = $mes + 1;
}
Saída:
Mês 1 - sobrou R$ 380,00
Mês 2 - sobrou R$ 260,00
Mês 3 - sobrou R$ 140,00
Mês 4 - sobrou R$ 20,00
Aqui está o caso clássico de while: ninguém sabia de antemão que seriam quatro meses. Quem descobriu isso foi a condição.
for: quando o número de voltas já é conhecido
Quando você sabe quantas voltas quer, o for junta os três ingredientes numa linha só, separados por ponto e vírgula. A mesma contagem de 1 a 10 do começo do guia fica assim:
<?php
for ($contador = 1; $contador <= 10; $contador++) {
echo $contador . "\n";
}
A anatomia da primeira linha, na ordem:
- $contador = 1 — o ponto de partida. Roda uma única vez, antes da primeira volta.
- $contador <= 10 — a condição. É testada antes de cada volta.
- $contador++ — o passo. Roda no fim de cada volta, automaticamente.
A vantagem do for é que o passo fica visível na primeira linha. Você não tem como esquecer de incrementar, porque o incremento está no cabeçalho do laço, não perdido no meio do bloco. Uma tabuada do 7 sai em quatro linhas:
<?php
$numero = 7;
for ($multiplicador = 1; $multiplicador <= 10; $multiplicador++) {
echo $numero . ' x ' . $multiplicador . ' = ' . ($numero * $multiplicador) . "\n";
}
Saída:
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
E o acumulador também funciona com for, quando o que você percorre é uma lista de tamanho conhecido:
<?php
$notas = [7.5, 4.0, 9.0, 6.5];
$soma = 0;
for ($posicao = 0; $posicao < count($notas); $posicao++) {
$soma = $soma + $notas[$posicao];
}
echo 'Média da turma: ' . number_format($soma / count($notas), 2, ',', '.') . "\n";
Saída:
Média da turma: 6,75
while ou for: tabela de decisão
| Situação | Laço indicado | Por quê |
|---|---|---|
| Contar de 1 a 100 | for | O número de voltas é conhecido antes de começar. |
| Percorrer uma lista de preços | for | O tamanho da lista já está definido por count(). |
| Descontar parcelas até o saldo acabar | while | Quantas parcelas cabem só se descobre repetindo. |
| Pedir a senha até o usuário acertar | while | Pode ser uma tentativa ou vinte. |
| Repetir um menu até escolherem "sair" | while | Depende da decisão de quem está usando. |
Nenhum dos dois é mais avançado que o outro. Tudo que dá para fazer com for dá para fazer com while e vice-versa — a escolha é sobre qual dos dois deixa a intenção mais óbvia para quem lê o código depois.
O loop infinito que todo iniciante escreve uma vez
Este é o rito de passagem. O código abaixo está sintaticamente perfeito e nunca termina:
<?php
$contador = 1;
while ($contador <= 10) {
echo $contador . "\n";
}
Faltou a linha que muda $contador. Como a variável fica valendo 1 para sempre, a condição é verdadeira para sempre e o PHP imprime "1" até alguém interromper. No terminal, você para com Ctrl + C; no navegador, fechando a aba ou o editor. Não estragou nada, é só barulho.
A variação sorrateira do mesmo erro é mudar a variável errada, ou mudar para o lado errado:
<?php
$contador = 10;
while ($contador <= 10) {
echo $contador . "\n";
$contador = $contador - 1;
}
Aqui a variável muda a cada volta, mas para baixo, indo cada vez mais fundo na direção em que a condição continua verdadeira. Some para sempre. Sempre que um laço não terminar, faça uma pergunta única: qual valor faria essa condição virar falsa, e o meu bloco caminha para esse valor?
Outros dois erros clássicos
Errar por uma volta. Trocar <= por < muda o resultado sem dar erro nenhum. $contador < 10 imprime até 9; $contador <= 10 imprime até 10. Quando o total sai com um item a menos ou a mais, é quase sempre isso. Confira rodando com uma lista de três itens, que dá para conferir na mão.
Declarar o acumulador dentro do laço. Se $total = 0 estiver dentro das chaves, ele volta a zero em cada volta e o resultado final é sempre o último valor, não a soma. Regra fixa: o que precisa lembrar do passado mora fora do laço; o que é descartável a cada volta mora dentro.
Repetir esses dois erros de propósito, uma vez cada, ensina mais do que ler sobre eles. Depois disso, o caminho é volume: nossa lista de exercícios de lógica de programação com resposta tem uma sequência inteira de contagens, somas e tabuadas para você escrever antes de olhar o gabarito.
Como praticar sem instalar nada
Para exercitar laço você não precisa de servidor, nem de banco de dados, nem de projeto. Precisa de um lugar onde escrever cinco linhas e ver a saída na hora. No Aulab, os exercícios de programação rodam num editor de PHP dentro do próprio navegador, então o aluno escreve o laço, executa e já compara a saída com o que era esperado — e o professor recebe a entrega para aprovar ou devolver com um comentário pedindo o ajuste. Se você dá aula e quer esse ciclo montado, dá para criar uma conta e testar com uma turma antes de decidir qualquer coisa.
Perguntas frequentes
Qual a diferença entre while e for em PHP?
Os dois repetem um bloco enquanto uma condição for verdadeira. A diferença é onde ficam o valor inicial e o incremento: no for eles ficam no cabeçalho do laço, junto da condição; no while ficam espalhados, o inicial antes do laço e o incremento dentro do bloco. Na prática, use for quando souber o número de voltas e while quando o fim depender de algo que só se descobre repetindo.
Como parar um loop infinito em PHP?
Se estiver rodando no terminal, pressione Ctrl + C. Se estiver num editor no navegador, feche a aba ou recarregue a página. Depois, olhe o bloco do laço e procure a linha que deveria mudar a variável da condição — em geral ela não existe, ou está mudando a variável na direção errada.
Por que meu contador imprime um número a menos do que eu queria?
Quase sempre é a comparação. < para antes de chegar no limite e <= inclui o limite. Em listas, lembre também que a primeira posição é 0 e a última é count($lista) - 1, então percorrer array pede < count($lista).
Preciso decorar a sintaxe do for?
Não. Escreva os três pedaços sempre na mesma ordem — valor inicial, condição, passo — e em poucos dias sai automático. Enquanto não sair, escreva o laço primeiro como while, que é mais falado, e depois traduza para for. Fazer essa tradução algumas vezes é um exercício ótimo por si só.
Existe laço para percorrer lista sem contador em PHP?
Existe: o foreach, que anda item a item sem você precisar controlar posição. Ele é o mais usado no dia a dia com listas. Vale conhecer depois que while e for estiverem firmes, porque é justamente controlar o contador na mão que ensina o que está acontecendo por dentro.