PHP para Iniciantes: Estruturas de Controle - CONTINUE
"Continue a nadar" é uma frase que marcou toda uma geração e que remete a sensação de loops infinitos, certo? Mas se você partir desse ponto de vista, vai acabar tendo uma ideia errada. Na programação, continue
é um verbo executado dentro de um laço e não é exatamente um "Ok, continue o que está fazendo" (se fosse o caso, bastaria não colocar instrução alguma...), está mais para "Pera, deu ruim, encerra aqui e continue do próximo laço".
Como assim, Kiko?
Calma, vamos do começo.
Uma reflexão sobre semântica
O verbo continue
afeta as mesmas estruturas que o break
: while
, do-while
, for
, foreach
e switch
. No entanto, peço que evite utilizar em switch
, especificamente, pois não faz sentido algum e a partir do PHP 7.3 já está gerando Warning - o que significa que em algum momento será um erro, oficialmente falando.
Ok, Kiko, eu nem vi switch ainda e você já tá falando o que não usar?
Hehehehe, sim... Faz parte, né?
Voltando a reflexão, vamos relembrar a semântica simplificada do for
:
PARA (configuração dos loops) FAÇA (ação)
Certo? Nesse cenário, o continue
seria um verbo acionado dentro da ação
. Por tanto, sua reflexão precisa ser a nível de unicidade de um laço. Então imagine que você tem algum critério para processar cada laço, mas que esse critério não deve interromper todo o fluxo, apenas ignorar os laços que não forem aceitos.
Isso não é a mesma coisa que o
break
, Kiko?
Não! Vai ficar mais claro a seguir. Mas o ponto é que o break
ENCERRA os laços, enquanto o continue
apenas salta para a próxima iteração.
Voltando ao cenário, geralmente os critérios são feitos em if
e, sendo o caso, nós temos a semântica SE (isso) ENTÃO (aquilo)
. Aqui, aquilo = continue
. Com isso, a semântica do continue
se soma à semântica do if
: SE (isso) ENTÃO CONTINUE PARA A PRÓXIMA ITERAÇÃO
.
continue
=CONTINUE PARA A PRÓXIMA ITERAÇÃO
? Orra, Kiko... Não tinha algo mais curto não?
Se o cenário fosse uma fila de atendimento, seria CHAME O PRÓXIMO
. Tudo depende do contexto.
A sintaxe
Bem, agora que você já entendeu a semântica, você pode aplicar o continue
do mesmo jeito que o break
, exceto que o inteiro colocado posteriormente representa qual dos laços encadeados você quer afetar.
Como assim, Kiko?
Bem, você lembra da sintaxe break <número>
? Também temos continue <número>
. Mas na minha explicação do break
, eu comentei que era a quantidade de laços a encerrar, porque é basicamente o que ele faz. Já o continue, não. Apenas um laço recebe o comando continue
, o número que você informa serve para identificar a profundidade onde o comando tem de afetar.
Vamos para o exemplo? Imagine que temos uma sequência numérica e, a partir dela, queremos extrair os números pares. Tem algumas formas de se fazer isso... A melhor é com array_filter
, mas não vem ao caso. A ideia aqui é usar uma estrutura onde seja possível aplicar o continue
, ou seja, while
/ do-while
/ for
/ foreach
. Escolhi o último, porque é o mais simples de ler. Vamos lá?
<?php
$numeros = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function ehPar(int $numero): bool
{
return ($numero % 2) === 0; // resto da divisão por 2 é estritamente igual a 0
}
$pares = []; // lista de pares a popular
foreach ($numeros as $numero) {
if (! ehPar($numero)) { // se não for par
continue; // continue para a próxima iteração
}
// se for par
$pares[] = $numero; // coloque na lista de pares
}
var_dump($pares); // array(0, 2, 4, 6, 8)
Ué, Kiko, não era
continue <número>
?
Sim! Mas se você não informar nada, será o equivalente a continue 1
, assim como no break
. Nesse caso, como só tinha um loop, era essa minha intenção mesmo.
Então você pode dar algum exemplo real onde o
continue
afeta algum laço acima, Kiko?
Er... Ok, deixe-me pensar um pouco.

Ok, tive uma ideia. Imagine que, por algum motivo, você tem uma lista de dados completamente bagunçados. É uma estrutura similar a uma matriz (array dentro de array), só que as colunas estão desordenadas. Você precisa percorrer todo o array para coletar os dados cujo primeiro valor inteiro é par. Isso vai gerar alguns continue
, vamos ver? Bom, acho que o ideal é fazer em partes.
A entrada
$bagunca = [
['K', 1.83, 0, 'Kiko'],
[3, 'Y', 1.73, 'Medalha'],
['derBrian', 8, 'V', 1.69],
];
A saída esperada
$resultado = [
['K', 1.83, 0, 'Kiko'],
['derBrian', 8, 'V', 1.69],
];
Os laços
Bem, Antes de qualquer coisa, nós precisamos percorrer o array, certo? Começamos com um primeiro foreach:
foreach ($bagunca as $item) {
// a mágica vai acontecer aqui
// onde $item é um array, por exemplo, ['K', 1.83, 0, 'Kiko']
}
Então, precisaremos percorrer o array $item
para encontrar a primeira "propriedade" que é inteira. Para validar, usaremos a função is_int()
:
// dentro do foreach de cima
foreach ($item as $valor) {
if (is_int($valor)) {
// o que acontece?
}
// e se não for?
}
Aqui temos duas possibilidades: tratar com break
ao encontrar (if positivo
) ou com continue
ao não encontrar (if negativo
). Como a aula é sobre continue
, já sabe o que escolhi:
foreach($item as $valor) {
if (! is_int($valor)) {
continue;
}
// ok, mas o que acontece quando é int?
}
Já temos um exemplo, uhuuu... Mas ainda falta validar se o inteiro é par. O que acontece se não for? Bem, aquele $item
torna-se inválido. Nesse caso, precisamos saltar para o próximo $item
, que é gerado no loop de fora......... Ok, tá virando bagunça. Vamos juntar o que temos até agora:
foreach ($bagunca as $item) {
foreach ($item as $valor) {
if (! is_int($valor)) {
continue;
}
// alguma mágica aqui...
}
// e esperamos que, ao chegar aqui, todas as validações passaram e precisamos incluir esse $item em algum lugar
}
Para validar se $valor
é par, usaremos a expressão ($valor % 2) === 0
, que checa se é divisível por 2. Mas como a ideia é validar com continue
, precisamos negar essa sentença, procurando pelos ímpares. Ou seja, basta trocar o ===
por !==
:
foreach ($bagunca as $item) {
foreach ($item as $valor) {
if (! is_int($valor)) {
continue;
}
if (($valor % 2) !== 0) {
continue 2; // ou seja, afete o 2° foreach de dentro para fora, que é o foreach($bagunca)
}
// e se chegou até aqui, é porque validou tudo! ou seja, vamos encerrar esse loop
break;
}
// TODO
}
E agora? Já validamos tudo:
- se não for
int
, continua buscando o inteiro. Nesse cenário, é garantido que ao menos um dos dados em$item
é inteiro, então não se preocupe com a possibilidade de não vir um; - se não for par, ignoramos aquele
$item
e passamos para o próximo; - se for
int
e par, então o$item
passou nos critérios e deve ser armazenado em...$resultado
! Variável que ainda não criamos. Vamos criar logo?
<?php
$bagunca = [
['K', 1.83, 0, 'Kiko'],
[3, 'Y', 1.73, 'Medalha'],
['derBrian', 8, 'V', 1.69],
];
$resultado = [];
foreach ($bagunca as $item) {
foreach ($item as $valor) {
if (! is_int($valor)) {
continue;
}
if (($valor % 2) !== 0) {
continue 2;
}
break;
}
$resultado[] = $item;
}
var_dump($resultado); // array(['K', 1.83, 0, 'Kiko'], ['derBrian', 8, 'V', 1.69])
Como seria esse código com
break
, Kiko?
Bem mais simples, mas mais difícil de ler:
<?php
$bagunca = [
['K', 1.83, 0, 'Kiko'],
[3, 'Y', 1.73, 'Medalha'],
['derBrian', 8, 'V', 1.69],
];
$resultado = [];
foreach ($bagunca as $item) {
foreach ($item as $valor) {
if (is_int($valor) && ($valor % 2) === 0) { // se é inteiro && é par
$resultado[] = $item; // então adiciona o item
break; // e fim de papo, encerra esse loop e começa o outro logo rapá
}
}
}
var_dump($resultado); // array(['K', 1.83, 0, 'Kiko'], ['derBrian', 8, 'V', 1.69])
Nesse cenário, como não tem mais nenhum código depois do foreach ($item)
, daria para trocar o break
por um continue 2
, mas o princípio não é esse. O break
aplicado ali ainda permite executar algum código depois do foreach
de dentro encerrar, sabe? O continue 2
não daria essa oportunidade.
Além disso, apesar de um único if
ser bonito, isso não é exatamente uma forma interessante de programar. Na visão do produto, você juntou duas regras em uma. Ao precisar dar uma manutenção, você precisará tomar cuidado pra sua alteração não afetar o comportamento de outra regra, sabe?
Quando é só duas regras é fácil ler. Eu já vi código com quase 10 regras em um if
só. Na real, eu já fiz isso e precisei dar manutenção depois... Não façam isso. Vai por mim.
Tá bom, Kiko... Mas só por curiosidade, como seria com
array_filter
?

<?php
$bagunca = [
['K', 1.83, 0, 'Kiko'],
[3, 'Y', 1.73, 'Medalha'],
['derBrian', 8, 'V', 1.69],
];
$resultado = array_filter($bagunca, function($item) {
$inteiros = array_filter($item, 'is_int'); // pega somente os valores inteiros
$primeiroInteiro = array_pop($inteiros);
return ($primeiroInteiro % 2) === 0; // se for par, entra no array_filter. se não, é ignorado
});
var_dump($resultado); // array(['K', 1.83, 0, 'Kiko'], ['derBrian', 8, 'V', 1.69])
Enfim, por hoje é só! Deu para entender as possibilidades de uso de um continue
? Espero que sim! E se curtiu, comenta e compartilha! No próximo artigo vamos falar sobre o tão mencionado switch
. Dá pra viver sem, mas é bom conhecer! Vai perder?
Inté!!