PHP

Estruturas de Repetição Já leu

10 min de leitura

Estruturas de Repetição
Se as estruturas de controle ensinam o programa a tomar decisões, as estruturas de repetição ensinam o programa a ter persistência. R

Se as estruturas de controle ensinam o programa a tomar decisões, as estruturas de repetição ensinam o programa a ter persistência. Repetir uma ação dez, cem ou um milhão de vezes sem escrever o código uma única vez extra — isso é o poder dos loops.

O PHP oferece quatro estruturas de repetição: for, foreach, while e do while. Cada uma tem um contexto onde brilha. Entender qual usar em cada situação é uma das marcas de um desenvolvedor experiente.


for

O for é ideal quando você sabe de antemão quantas vezes quer repetir algo. Sua estrutura tem três partes: inicialização, condição de continuação e incremento.

<?php

// Estrutura: for (inicialização; condição; incremento)
// 1. Inicialização: executada UMA vez, no início
// 2. Condição: verificada ANTES de cada iteração — se false, para
// 3. Incremento: executado APÓS cada iteração

for ($i = 0; $i < 5; $i++) {
    echo "Iteração $i\n";
}
// Saída: Iteração 0, Iteração 1, Iteração 2, Iteração 3, Iteração 4

// Contando de trás para frente
for ($i = 5; $i > 0; $i--) {
    echo "$i ";
}
// Saída: 5 4 3 2 1

// Incremento de dois em dois
for ($i = 0; $i <= 10; $i += 2) {
    echo "$i "; // 0 2 4 6 8 10
}

// Iterando sobre um array com índice numérico
$frutas = ["maçã", "banana", "laranja", "uva"];

for ($i = 0; $i < count($frutas); $i++) {
    // count() retorna o número de elementos do array
    echo "$i: {$frutas[$i]}\n";
}
// 0: maçã
// 1: banana
// 2: laranja
// 3: uva

foreach

O foreach é a estrutura de repetição mais usada no PHP cotidiano. Ele foi feito especificamente para iterar sobre arrays e objetos, sem a necessidade de controlar um índice manualmente.

<?php

$frutas = ["maçã", "banana", "laranja", "uva"];

// Forma simples — acessa apenas o valor
foreach ($frutas as $fruta) {
    echo $fruta . "\n";
}

// Forma com chave e valor — acessa índice e valor
foreach ($frutas as $indice => $fruta) {
    echo "$indice: $fruta\n";
}
// 0: maçã
// 1: banana
// 2: laranja
// 3: uva

// foreach com array associativo (chave => valor)
$pessoa = [
    "nome"  => "Ana",
    "idade" => 28,
    "cidade" => "São Paulo",
];

foreach ($pessoa as $chave => $valor) {
    echo "$chave: $valor\n";
}
// nome: Ana
// idade: 28
// cidade: São Paulo

// foreach com array de arrays — muito comum em dados de banco
$usuarios = [
    ["nome" => "Ana",    "idade" => 28],
    ["nome" => "Carlos", "idade" => 35],
    ["nome" => "Beatriz","idade" => 22],
];

foreach ($usuarios as $usuario) {
    // Cada $usuario é um array associativo
    echo "{$usuario['nome']} tem {$usuario['idade']} anos.\n";
}

Modificando valores com foreach por referência

Por padrão, o foreach trabalha com uma cópia do valor. Se você precisar modificar os elementos originais do array durante a iteração, use o operador & para passar por referência:

<?php

$precos = [10.0, 25.5, 8.0, 42.0];

// Sem referência — $preco é uma cópia, o array original não muda
foreach ($precos as $preco) {
    $preco *= 1.1; // aplica 10% de aumento — mas não salva!
}
var_dump($precos[0]); // float(10) — não mudou

// Com referência (&) — modifica o array original
foreach ($precos as &$preco) {
    $preco *= 1.1; // agora salva no array original
}
unset($preco); // IMPORTANTE: sempre destrua a referência após o loop
               // Sem isso, a variável $preco ainda aponta para o último elemento
               // e pode causar bugs sutis se o array for reutilizado

var_dump($precos[0]); // float(11) — mudou corretamente

O unset($preco) após o loop é uma das armadilhas mais clássicas do PHP. Nunca se esqueça dele ao usar referências em foreach.


while

O while repete enquanto uma condição for verdadeira. É ideal quando você não sabe de antemão quantas iterações serão necessárias — o loop termina quando a condição se torna falsa.

<?php

// Estrutura básica
$contador = 0;

while ($contador < 5) {
    echo "Contador: $contador\n";
    $contador++; // sem isso, loop infinito!
}

// Exemplo prático: lendo um arquivo linha por linha
// fgets() retorna false quando chega ao fim do arquivo
$arquivo = fopen("dados.txt", "r");

if ($arquivo) {
    while (($linha = fgets($arquivo)) !== false) {
        // processa cada linha
        echo trim($linha) . "\n";
    }
    fclose($arquivo);
}

// Simulando paginação — avança páginas enquanto houver resultados
$pagina  = 1;
$porPagina = 10;
$totalRegistros = 47;

while (($pagina - 1) * $porPagina < $totalRegistros) {
    $inicio = ($pagina - 1) * $porPagina + 1;
    $fim    = min($pagina * $porPagina, $totalRegistros);
    echo "Processando registros $inicio a $fim\n";
    $pagina++;
}
// Processando registros 1 a 10
// Processando registros 11 a 20
// Processando registros 21 a 30
// Processando registros 31 a 40
// Processando registros 41 a 47

do while

O do while é semelhante ao while, mas com uma diferença fundamental: o bloco de código é executado pelo menos uma vez antes de verificar a condição. Isso é útil quando você precisa que o código rode ao menos uma iteração independentemente da condição.

<?php

// do while garante ao menos uma execução
$tentativas = 0;

do {
    echo "Tentativa $tentativas\n";
    $tentativas++;
} while ($tentativas < 3);
// Tentativa 0
// Tentativa 1
// Tentativa 2

// Caso clássico: validação de entrada do usuário
// (em ambiente CLI — linha de comando)
do {
    $entrada = readline("Digite um número entre 1 e 10: ");
    $numero  = (int) $entrada;
} while ($numero < 1 || $numero > 10);

echo "Você digitou: $numero";

// Processamento com retry — tenta operação até ter sucesso ou esgotar tentativas
$maxTentativas = 3;
$tentativa     = 0;
$sucesso       = false;

do {
    $tentativa++;
    // simula uma operação que pode falhar
    $sucesso = rand(0, 1) === 1;
    echo "Tentativa $tentativa: " . ($sucesso ? "sucesso" : "falhou") . "\n";
} while (!$sucesso && $tentativa < $maxTentativas);

break e continue

Dois comandos que controlam o fluxo dentro de loops:

  • break — interrompe o loop completamente
  • continue — pula para a próxima iteração, ignorando o restante do bloco atual
<?php

$numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// break — para o loop quando encontra o primeiro número maior que 5
foreach ($numeros as $n) {
    if ($n > 5) {
        break; // sai do foreach completamente
    }
    echo "$n "; // 1 2 3 4 5
}

// continue — pula os números pares
foreach ($numeros as $n) {
    if ($n % 2 === 0) {
        continue; // vai para a próxima iteração
    }
    echo "$n "; // 1 3 5 7 9
}

// break com nível numérico — quebra loops aninhados
// break 2 sai de dois níveis de loop de uma vez
for ($i = 0; $i < 3; $i++) {
    for ($j = 0; $j < 3; $j++) {
        if ($i === 1 && $j === 1) {
            break 2; // sai dos dois loops
        }
        echo "($i,$j) ";
    }
}
// (0,0) (0,1) (0,2) (1,0)

Evitando loops infinitos

Um loop infinito trava o processo PHP e pode derrubar o servidor. As causas mais comuns são:

<?php

// ✗ LOOP INFINITO — condição nunca se torna false
$i = 0;
while ($i < 10) {
    echo $i;
    // esquecemos de incrementar $i!
}

// ✗ LOOP INFINITO — incremento errado
for ($i = 10; $i > 0; $i++) { // $i começa em 10 e só aumenta
    echo $i;
}

// ✓ Sempre verifique:
// 1. A variável de controle está sendo modificada dentro do loop?
// 2. A condição de parada é realmente atingível?
// 3. Há algum caso extremo (array vazio, valor zero) que precisa ser tratado?

// Proteção com contador de segurança — útil em loops complexos
$maxIteracoes = 1000;
$iteracao     = 0;

while (condicaoComplexaDificilDeVerificar()) {
    if ($iteracao++ > $maxIteracoes) {
        throw new RuntimeException("Loop excedeu o limite de segurança.");
    }
    // processamento...
}

Qual loop usar em cada situação

<?php

$nomes = ["Ana", "Bruno", "Carla"];

// foreach — iterando arrays ou coleções (uso mais comum)
foreach ($nomes as $nome) {
    echo $nome . "\n";
}

// for — quando o índice numérico importa ou você sabe o número de iterações
for ($i = 0; $i < count($nomes); $i++) {
    echo "$i: {$nomes[$i]}\n";
}

// while — condição desconhecida, leitura de streams, retries
$posicao = 0;
while ($posicao < count($nomes)) {
    echo $nomes[$posicao] . "\n";
    $posicao++;
}

// do while — quando precisa de ao menos uma execução garantida
$tentativa = 0;
do {
    echo "Tentativa $tentativa\n";
    $tentativa++;
} while ($tentativa < 3);

Boas práticas em loops

Prefira foreach para arrays. É mais legível, menos propenso a erros de índice e expressa melhor a intenção de "percorrer cada item".

Evite modificar o array que está sendo iterado. Se precisar filtrar ou transformar, prefira funções como array_filter() e array_map() — veremos no próximo módulo.

Não chame funções pesadas na condição do for. O código a seguir chama count() a cada iteração:

<?php

// ✗ count() é chamado em cada iteração
for ($i = 0; $i < count($array); $i++) { ... }

// ✓ Calcule uma vez só, antes do loop
$total = count($array);
for ($i = 0; $i < $total; $i++) { ... }

Sempre destrua referências após foreach com &. Como vimos, unset($variavel) após o loop é obrigatório.

Nomeie a variável de iteração com clareza. $usuario é melhor que $u. $produto é melhor que $p. $i é aceitável apenas para contadores numéricos simples.


Resumo

Estrutura Quando usar
for Número de iterações conhecido, índice numérico importa
foreach Iterar arrays e objetos — uso mais comum no PHP
while Condição desconhecida, streams, operações com retry
do while Ao menos uma execução é garantida antes de verificar
break Interromper o loop completamente
continue Pular para a próxima iteração
break N Sair de N níveis de loops aninhados

Referências e leituras para aprofundar

Comentários

Mais em PHP

Artigo 50 — Projeto Final Parte 1: Planejamento e Arquitetura
Artigo 50 — Projeto Final Parte 1: Planejamento e Arquitetura

Chegamos ao projeto final. Quarenta e nove artigos de fundamentos, orientação...

Artigo 40 — Boas Práticas e Código Limpo em PHP
Artigo 40 — Boas Práticas e Código Limpo em PHP

Boas práticas não são regras arbitrárias inventadas por puristas. São soluçõe...

Clean Architecture com PHP
Clean Architecture com PHP

Clean Architecture, formulada por Robert C. Martin, organiza o código em cama...