Aulab Criar conta grátis
Para aprender

Laços de repetição em PHP: while e for explicados

Atualizado em 30 de agosto de 2026

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:

  1. $contador = 1 — o ponto de partida. Roda uma única vez, antes da primeira volta.
  2. $contador <= 10 — a condição. É testada antes de cada volta.
  3. $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.

Leia também

Sua turma inteira num lugar só

Poste aulas e exercícios, corrija com devolutiva e acompanhe o progresso de cada aluno — o Aulab reúne tudo isso numa turma só.