Instrução Switch do PHP: Um Guia Completo
A instrução switch do PHP controla o fluxo do código testando uma expressão contra múltiplos valores possíveis com sintaxe clara e eficiente.
A instrução switch do PHP compara uma expressão com uma lista de valores possíveis e executa o bloco correspondente. É a alternativa mais limpa a uma longa cadeia de instruções if...elseif...else quando você está testando a mesma variável contra muitos valores fixos.
Esta página cobre a sintaxe, como o matching e o fall-through realmente funcionam, exemplos executáveis reais, a alternativa match do PHP 8 e as armadilhas que confundem as pessoas.
Sintaxe
switch (expression) {
case value1:
// runs when expression == value1
break;
case value2:
// runs when expression == value2
break;
default:
// runs when nothing above matched
}A expression é avaliada uma vez. Seu resultado é então comparado, de cima para baixo, com cada valor de case usando comparação solta (==). No primeiro match, o PHP começa a executar as instruções daquele case e continua até encontrar um break (ou o fim do switch). O bloco default opcional é executado quando nenhum case foi correspondido — por convenção, ele vai por último.
Um exemplo funcional
Este exemplo mapeia um número de dia para um nome e imprime o resultado:
<?php
$day = 3;
switch ($day) {
case 1:
echo "Monday";
break;
case 2:
echo "Tuesday";
break;
case 3:
echo "Wednesday";
break;
default:
echo "Another day";
}
// Output: WednesdayComo $day é 3, o terceiro case corresponde, "Wednesday" é impresso e break para a execução antes do bloco default.
Por que break importa: fall-through
Se você esquecer um break, a execução "cai" para o próximo case e continua até encontrar um. Este é o bug mais comum do switch:
<?php
$role = "editor";
switch ($role) {
case "editor":
echo "Can edit. ";
// no break — falls through!
case "viewer":
echo "Can view.";
break;
}
// Output: Can edit. Can view.Aqui "editor" correspondeu, mas sem break o PHP também executou o bloco viewer.
Fall-through intencional (agrupando cases)
O fall-through é ocasionalmente útil de propósito: empilhar cases vazios permite que vários valores compartilhem um bloco.
<?php
$letter = "e";
switch ($letter) {
case "a":
case "e":
case "i":
case "o":
case "u":
echo "Vowel";
break;
default:
echo "Consonant";
}
// Output: VowelUsando switch com condição true
Um switch também pode substituir uma sequência de if...elseif para verificações de intervalo. Faça switch em true e coloque uma expressão booleana em cada case:
<?php
$score = 82;
switch (true) {
case $score >= 90:
echo "A";
break;
case $score >= 80:
echo "B";
break;
case $score >= 70:
echo "C";
break;
default:
echo "F";
}
// Output: BO primeiro case cuja expressão é igual a true vence, portanto a ordem importa — liste a condição mais restrita primeiro.
switch vs match (PHP 8+)
O PHP 8 adicionou a expressão match, um irmão mais estrito do switch. Use match quando você simplesmente mapeia um valor para um resultado:
<?php
$status = 404;
$message = match ($status) {
200, 201 => "Success",
404 => "Not Found",
500 => "Server Error",
default => "Unknown",
};
echo $message;
// Output: Not FoundPrincipais diferenças:
switch | match | |
|---|---|---|
| Comparação | solta (==) | estrita (===) |
| Fall-through | sim (precisa de break) | nenhum |
| Retorna um valor | não | sim (é uma expressão) |
Valor não correspondido, sem default | não faz nada | lança UnhandledMatchError |
Armadilha da comparação solta
Como switch usa ==, um 0 numérico pode corresponder a uma string não vazia em código mais antigo. No PHP 8+ as regras de comparação string-para-número foram restringidas, mas mantenha os tipos consistentes para evitar surpresas:
<?php
$value = 0;
switch ($value) {
case "hello":
echo "matched hello";
break;
default:
echo "no match";
}
// Output (PHP 8+): no matchNo PHP 7, o mesmo código teria impresso matched hello porque 0 == "hello" era true. Em caso de dúvida, use match para comparação estrita.
Boas práticas
- Sempre adicione
breakapós cada case, a menos que você deliberadamente queira fall-through (e comente quando fizer isso). - Inclua um
defaultpara lidar com valores inesperados em vez de não fazer nada silenciosamente. - Agrupe cases relacionados empilhando rótulos
casevazios em vez de duplicar código. - Prefira
match(PHP 8+) quando você estiver retornando um valor ou precisar de comparação estrita. - Use
if...elseifquando você estiver testando expressões diferentes, não um valor contra muitos.
Tópicos relacionados
- PHP If...Else...Elseif — ramificação condicional
- PHP Operators — comparação e a expressão
match - PHP Loops — repetindo blocos de código