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.
- A anatomia do
if: condição entre parênteses e bloco entre chaves. else("senão") eelseif("senão, se"), e por que a ordem importa.ifdentro deif, eifsem 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
trueoufalse. - { … }
- 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:
6 >= 7? Não. Vai para o próximo.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.
| Escrita | Significado |
|---|---|
$nota = 10 | Guarde 10 em $nota |
$nota == 10 | $nota vale 10? (convertendo tipos) |
$nota === 10 | $nota vale 10 e é int? |
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 ifaqui 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ção | Prefira |
|---|---|
| Código PHP "puro" (lógica, cálculos) | Chaves { } |
| Pedaços de HTML que aparecem ou não | if: … endif; |
| Escolher entre dois valores curtos | Operador ternário (próxima aula: Operador Ternário) |
| Comparar uma variável com muitos valores fixos | match ou switch |
Quando dá errado
<?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) {.
<?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).
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).
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.
; 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.
<?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
| Forma | Exemplo |
|---|---|
if | if ($a > 0) { … } |
if + else | if ($a > 0) { … } else { … } |
if + elseif + else | if (…) { … } elseif (…) { … } else { … } |
else if (com chaves) | Igual ao elseif |
| Sintaxe alternativa | if (…): … elseif (…): … else: … endif; |
| Sem chaves (evite) | if ($a > 0) echo "positivo"; |
| Falsos | false 0 0.0 "" "0" [] null |
Exercícios
1. Complete o if
Complete para mostrar "Maior de idade" quando $idade for 18 ou mais:
2. Senão, se
Complete com a palavra que encadeia uma nova condição:
3. Fechar na sintaxe alternativa
Complete o fechamento:
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";elseifencadeia novas condições. O PHP para na primeira verdadeira, então a ordem importa.- Sempre use chaves: sem elas, o
ifsó 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 ifnão funciona).