PHP if, elseif, else

Até aqui, seus programas rodavam todas as linhas, de cima para baixo, sempre. Programas de verdade decidem: mostram "Aprovada" ou "Reprovada" conforme a nota, "Frete grátis" se a compra passar de 100 reais, a página de login se a pessoa não entrou. A ferramenta para isso é o if.

Você vai aprender
  • A anatomia do if: condição entre parênteses e bloco entre chaves.
  • else ("senão") e elseif ("senão, se"), e por que a ordem importa.
  • if dentro de if, e if sem chaves (e a armadilha que vem junto).
  • O que o PHP considera verdadeiro e falso, e por que comparar com ===.
  • O bug do = no lugar de ==, que não dá erro nenhum.
  • A sintaxe alternativa if: … endif;, usada no meio do HTML.

A ideia: uma bifurcação no caminho

"Se estiver chovendo, levo o guarda-chuva. Senão, levo os óculos de sol." Você toma decisões assim o dia todo: olha uma condição (está chovendo?), e a resposta é sim ou não. Conforme a resposta, faz uma coisa ou outra.

No PHP, if é "se" em inglês, e else é "senão". A condição é qualquer coisa que dê true (verdadeiro) ou false (falso), normalmente uma comparação como $nota >= 7 (veja Comparação e Booleanos).


if: fazer algo só se…

<?php
$nota = 8.5;
if ($nota >= 7) {
    echo "Aprovada!\n";
}
echo "Fim do boletim.\n";
if
A palavra que começa a decisão: "se".
( $nota >= 7 )
A condição, sempre entre parênteses. "A nota é maior ou igual a 7?" O PHP calcula e obtém true ou false.
{ … }
O bloco: as linhas que só rodam se a condição for true. Pode ter quantas linhas você quiser.
(recuo de 4 espaços)
As linhas de dentro ficam recuadas. O PHP não exige, mas é o que deixa claro, de olho, o que está dentro do if.
echo "Fim…"
Fora das chaves: roda sempre, com qualquer nota.
$ php aprovada.php
Aprovada!
Fim do boletim.

Agora troque a primeira linha por $nota = 5; e rode de novo:

$ php aprovada.php
Fim do boletim.          « a condição deu false: o bloco foi pulado

Repare que não há ; depois do ) nem depois do }. O ; fica só no fim dos comandos dentro do bloco.


else: senão…

Com else, você diz o que fazer quando a condição é falsa. Exatamente um dos dois blocos roda, nunca os dois, nunca nenhum.

<?php
$nota = 5;
if ($nota >= 7) {
    echo "Aprovada!\n";
} else {
    echo "Não foi dessa vez.\n";
}
$ php senao.php
Não foi dessa vez.

O else não tem condição: ele é "todo o resto". Ele vem logo depois do } do if.


elseif: mais de dois caminhos

A escola da Ana tem três situações: 7 ou mais, aprovado; de 5 a 7, recuperação; abaixo de 5, reprovado. Para isso, encadeie condições com elseif ("senão, se"):

<?php
$nota = 6;
if ($nota >= 7) {
    echo "Aprovado\n";
} elseif ($nota >= 5) {
    echo "Recuperação\n";
} else {
    echo "Reprovado\n";
}
$ php situacao.php
Recuperação

O PHP testa as condições de cima para baixo e para na primeira verdadeira:

  1. 6 >= 7? Não. Vai para o próximo.
  2. 6 >= 5? Sim. Roda "Recuperação" e pula todo o resto, até o fim do último }.

Repare que o elseif não precisa testar "$nota < 7": se chegou ali, é porque a condição de cima já deu falso. Você pode ter quantos elseif quiser, e o else no fim é opcional.

A ordem importa

Como o PHP para na primeira condição verdadeira, a ordem das condições muda o resultado:

<?php
$nota = 8;
if ($nota >= 5) {
    echo "Recuperação\n";
} elseif ($nota >= 7) {
    echo "Aprovado\n";
}
$ php ordem.php
Recuperação          « errado! 8 também é >= 5, e essa condição veio primeiro

A condição $nota >= 7 nunca vai ser alcançada com nota alta. A regra: em faixas de valores, comece pela mais restrita (a maior nota) e desça.

elseif ou else if?

Com chaves, as duas formas funcionam e fazem a mesma coisa: } else if (…) { é um else cujo bloco é outro if. A comunidade PHP (e o guia de estilo PSR-12; veja Padrões PSR) prefere elseif, junto. Na sintaxe alternativa com :, que você vai ver no fim da aula, só elseif funciona.

Missão: na lojinha da Ana, o frete é grátis para compras a partir de R$ 100, custa R$ 10,00 para compras a partir de R$ 50 e R$ 20,00 para as menores. Com $compra = 75, o programa deve mostrar Frete: R$ 10,00. Acrescente o elseif que falta.

<?php
$compra = 75;
if ($compra >= 100) {
    echo "Frete grátis!";
} else {
    echo "Frete: R$ 20,00";
}
<?php
$compra = 75;
if ($compra >= 100) {
    echo "Frete grátis!";
} elseif ($compra >= 50) {
    echo "Frete: R$ 10,00";
} else {
    echo "Frete: R$ 20,00";
}

Condições compostas e if dentro de if

Para testar duas coisas ao mesmo tempo, use os operadores lógicos: && ("e": as duas precisam ser verdadeiras) e || ("ou": basta uma).

<?php
$nota = 8;
$faltas = 12;
if ($nota >= 7 && $faltas <= 10) {
    echo "Aprovado\n";
} else {
    echo "Não aprovado\n";
}
$ php composta.php
Não aprovado          « nota boa, mas faltas demais

O problema dessa versão: o aluno não sabe por que não passou. Com um if dentro do outro (if aninhado), dá para dar a resposta certa a cada caso:

<?php
$nota = 8;
$faltas = 12;
if ($faltas <= 10) {
    if ($nota >= 7) {
        echo "Aprovado\n";
    } else {
        echo "Reprovado por nota\n";
    }
} else {
    echo "Reprovado por faltas\n";
}
$ php aninhado.php
Reprovado por faltas

Cada if de dentro fica recuado mais 4 espaços: assim você enxerga quais chaves fecham o quê. Evite passar de 2 ou 3 níveis; quando o código começa a "andar para a direita", geralmente dá para reescrever com &&, com elseif ou com um match.


if sem chaves (e a armadilha)

Se o bloco tem um único comando, as chaves são opcionais:

<?php
$nota = 9;
if ($nota >= 7) echo "Aprovado\n";
else echo "Reprovado\n";
$ php curto.php
Aprovado

Parece prático, mas esconde uma armadilha. A Ana quis mostrar duas mensagens para quem passou:

<?php
$nota = 3;
if ($nota >= 7)
    echo "Aprovado!\n";
    echo "Parabéns!\n";
$ php armadilha.php
Parabéns!          « com nota 3!

Sem chaves, o if só "pega" o primeiro comando. O segundo echo está recuado, o que engana o olho, mas para o PHP ele está fora do if e roda sempre. O recuo não significa nada para o PHP. Use chaves sempre, mesmo com uma linha só.


O que conta como verdadeiro?

A condição do if não precisa ser uma comparação. Qualquer valor serve: o PHP o converte para true ou false. Os valores que viram false são poucos, e vale a pena conhecê-los:

<?php
if (0) echo "verdadeiro\n"; else echo "0 é falso\n";
if ("0") echo "verdadeiro\n"; else echo "\"0\" é falso\n";
if ("0.0") echo "\"0.0\" é verdadeiro\n";
if ([]) echo "verdadeiro\n"; else echo "[] é falso\n";
if (" ") echo "\" \" é verdadeiro\n";
$ php verdade.php
0 é falso
"0" é falso
"0.0" é verdadeiro
[] é falso
" " é verdadeiro
Viram false (falsos)Todo o resto vira true, inclusive…
false, 0, 0.0, "" (texto vazio), "0", [] (array vazio), null"0.0", " " (um espaço), "false", -1, [0]

Por isso if ($nome) é um jeito comum de perguntar "o nome foi preenchido?". Mas cuidado com o "0": se alguém digitar o número zero num campo, o if acha que está vazio. E foi assim que o strpos enganou a Ana na aula de Funções de String: a posição 0 virou false.


Compare com ===

O == compara valores convertendo os tipos se precisar; o === exige valor e tipo iguais (veja Comparação (== e ===)). Dados de formulário sempre chegam como texto:

<?php
$idade = "18";          // veio de um formulário: é texto
if ($idade == 18) {
    echo "== : igual\n";
}
if ($idade === 18) {
    echo "=== : igual\n";
} else {
    echo "=== : diferente (string × int)\n";
}
$ php estrito.php
== : igual
=== : diferente (string × int)

Prefira === e !==: o resultado é previsível. Quando o tipo pode variar (como o texto do formulário), converta antes, de propósito: if ((int) $idade === 18).


O bug do = no lugar de ==

Esse é o erro mais famoso de quem começa, em qualquer linguagem. Repare no if:

<?php
$nota = 5;
if ($nota = 10) {
    echo "Nota máxima!\n";
}
echo "A nota agora é $nota\n";
$ php atribuicao.php
Nota máxima!            « com nota 5?!
A nota agora é 10       « e a nota mudou!

Um = só não compara: ele atribui (guarda o valor; veja Operadores de Atribuição). A linha if ($nota = 10) fez duas coisas: guardou 10 em $nota e usou esse 10 como condição. E 10 é "verdadeiro". Resultado: o bloco roda sempre e a variável é estragada. O PHP não mostra erro nem aviso, porque atribuir dentro de um if é permitido.

EscritaSignificado
$nota = 10Guarde 10 em $nota
$nota == 10$nota vale 10? (convertendo tipos)
$nota === 10$nota vale 10 e é int?
Um truque de defesa: a constante à esquerda

Algumas pessoas escrevem if (10 === $nota). Se esquecerem um =, sai if (10 = $nota), que o PHP recusa, porque não dá para guardar algo dentro do número 10:

$ php yoda.php

Parse error: syntax error, unexpected token "=" in /home/ana/php/yoda.php on line 3

Esse estilo tem até apelido, "condição Yoda" (pela ordem invertida das frases do personagem). Não é obrigatório; usar sempre === e ler com atenção já resolve.


Sintaxe alternativa: if: … endif;

Quando o PHP está no meio de uma página HTML (veja PHP Dentro do HTML), as chaves ficam perdidas entre as tags. Por isso existe uma segunda forma de escrever o if: os dois-pontos : abrem o bloco, e endif; ("fim do se") fecha.

<?php $nota = 8.5; ?>
<h1>Boletim</h1>
<?php if ($nota >= 7): ?>
    <p class="ok">Aprovada com <?= $nota ?>!</p>
<?php elseif ($nota >= 5): ?>
    <p class="aviso">Recuperação.</p>
<?php else: ?>
    <p class="erro">Reprovada.</p>
<?php endif; ?>
if (…):
Os dois-pontos no lugar do {.
elseif (…):
Junto, obrigatoriamente: else if aqui dá erro.
else:
Também com dois-pontos.
endif;
Fecha tudo, no lugar do }, com ponto e vírgula.
?> HTML <?php
Entre um pedaço e outro, o PHP "sai" e você escreve HTML puro. Só o HTML do caminho escolhido vai para a página.
$ php boletim.php
<h1>Boletim</h1>
    <p class="ok">Aprovada com 8.5!</p>

Os parágrafos de "Recuperação" e "Reprovada" nem aparecem no HTML gerado: o navegador nunca fica sabendo deles. Mudou a nota, muda o HTML.

Experimente: rode, veja a aba Resultado e a aba Código-fonte HTML. Depois troque a nota para 6 e para 3.

<?php $nota = 8.5; ?>
<h1>Boletim da Carla</h1>
<?php if ($nota >= 7): ?>
    <p style="color: green">Aprovada com <?= $nota ?>!</p>
<?php elseif ($nota >= 5): ?>
    <p style="color: orange">Recuperação.</p>
<?php else: ?>
    <p style="color: red">Reprovada.</p>
<?php endif; ?>
SituaçãoPrefira
Código PHP "puro" (lógica, cálculos)Chaves { }
Pedaços de HTML que aparecem ou nãoif: … endif;
Escolher entre dois valores curtosOperador ternário (próxima aula: Operador Ternário)
Comparar uma variável com muitos valores fixosmatch ou switch

Quando dá errado

expecting "(" — esqueceu os parênteses
<?php
$nota = 8;
if $nota >= 7 {
    echo "Aprovado\n";
}
$ php sem-parenteses.php

Parse error: syntax error, unexpected variable "$nota", expecting "(" in /home/ana/php/sem-parenteses.php on line 3

O que significa: "variável $nota inesperada, esperava (". Em PHP, a condição do if sempre vai entre parênteses (em Python não precisa, e quem vem de lá esquece).

Como consertar: if ($nota >= 7) {.

Unclosed '{' — faltou fechar a chave
<?php
$nota = 8;
if ($nota >= 7) {
    echo "Aprovado\n";
$ php sem-chave.php

Parse error: Unclosed '{' on line 3 in /home/ana/php/sem-chave.php on line 5

O que significa: "chave aberta na linha 3 e não fechada". O PHP chegou ao fim do arquivo (linha 5) procurando o }. A mensagem é boa: ela diz onde a chave foi aberta.

Como consertar: feche o bloco. Com if aninhados, conte: cada { precisa de um }. Editores mostram o par de cada chave quando você coloca o cursor nela (veja Editores e IDEs).

unexpected token "elseif" — elseif depois do else
<?php
$nota = 3;
if ($nota >= 7) {
    echo "Aprovado\n";
} else {
    echo "Reprovado\n";
} elseif ($nota >= 5) {
    echo "Recuperação\n";
}
$ php ordem-else.php

Parse error: syntax error, unexpected token "elseif", expecting end of file in /home/ana/php/ordem-else.php on line 7

O que significa: o else é sempre o último: ele é "todo o resto". Depois dele, a estrutura acabou, e um elseif solto não faz sentido.

Como consertar: a ordem é sempre if → elseif (quantos quiser) → else (opcional, no máximo um).

unexpected token "if", expecting ":" — else if na sintaxe alternativa
<?php
$nota = 8;
if ($nota >= 7):
    echo "Aprovado\n";
else if ($nota >= 5):
    echo "Recuperação\n";
endif;
$ php else-if.php

Parse error: syntax error, unexpected token "if", expecting ":" in /home/ana/php/else-if.php on line 5

O que significa: na sintaxe com :, o PHP esperava else: e encontrou outro if.

Como consertar: escreva elseif, junto.

O bloco roda sempre: um ; depois do if
<?php
$nota = 3;
if ($nota >= 7);
{
    echo "Aprovado\n";
}
$ php ponto-virgula.php
Aprovado            « com nota 3

O que significa: o ; logo depois do ) é um comando vazio. O if ficou assim: "se a nota for >= 7, não faça nada". As chaves de baixo viraram um bloco solto, que roda sempre. Nenhum erro, nenhum aviso.

Como consertar: nunca coloque ; depois do ) do if. Mantenha a { na mesma linha do if: fica mais fácil de perceber.

Undefined variable na condição
<?php
if ($naoExiste > 5) { echo "a"; } else { echo "b\n"; }
$ php indefinida.php

Warning: Undefined variable $naoExiste in /home/ana/php/indefinida.php on line 2
b

O que significa: a variável não existe (um erro de digitação ou um campo de formulário que não veio). O PHP avisa, trata como null e segue: null > 5 é falso.

Como consertar: confira o nome. Para dados que podem não existir, use isset ou ?? (veja ?? e ?->).


Referência

FormaExemplo
ifif ($a > 0) { … }
if + elseif ($a > 0) { … } else { … }
if + elseif + elseif (…) { … } elseif (…) { … } else { … }
else if (com chaves)Igual ao elseif
Sintaxe alternativaif (…): … elseif (…): … else: … endif;
Sem chaves (evite)if ($a > 0) echo "positivo";
Falsosfalse 0 0.0 "" "0" [] null

Exercícios

1. Complete o if

Complete para mostrar "Maior de idade" quando $idade for 18 ou mais:

if () { echo "Maior de idade"; }

2. Senão, se

Complete com a palavra que encadeia uma nova condição:

if ($n > 0) { echo "positivo"; } ($n < 0) { echo "negativo"; } else { echo "zero"; }

3. Fechar na sintaxe alternativa

Complete o fechamento:

<?php if ($logado): ?> <p>Olá!</p> <?php ?>

4. Com $x = 0;, o que mostra if ($x = 5) { echo "sim"; } else { echo "não"; }?

5. Qual destes valores faz um if rodar o bloco?

6. Com $nota = 9, o que mostra if ($nota >= 5) { echo "A"; } elseif ($nota >= 7) { echo "B"; } else { echo "C"; }?

Missão final: na página de produto da lojinha, mostre Esgotado se o estoque for 0, Últimas unidades! se for menor que 5, e Em estoque nos outros casos. Use a sintaxe alternativa (if:, elseif:, else:, endif;). Com $estoque = 3, a página deve mostrar "Últimas unidades!".

<?php $estoque = 3; ?>
<h2>Maçã — R$ 4,50/kg</h2>
<p>Em estoque</p>
<?php $estoque = 3; ?>
<h2>Maçã — R$ 4,50/kg</h2>
<?php if ($estoque === 0): ?>
    <p>Esgotado</p>
<?php elseif ($estoque < 5): ?>
    <p>Últimas unidades!</p>
<?php else: ?>
    <p>Em estoque</p>
<?php endif; ?>

Resumo

  • if (condição) { … } roda o bloco só quando a condição é verdadeira.
  • else é o "senão"; elseif encadeia novas condições. O PHP para na primeira verdadeira, então a ordem importa.
  • Sempre use chaves: sem elas, o if só pega o primeiro comando, e o recuo engana.
  • Falsos: false, 0, 0.0, "", "0", [], null. O resto é verdadeiro.
  • Compare com ===. Um = só atribui, e o bug não dá erro nenhum.
  • No meio do HTML, use if: … elseif: … else: … endif; (aqui, else if não funciona).