PHP 8.1.31 Released!

switch

(PHP 4, PHP 5, PHP 7, PHP 8)

A declaração switch é similar a uma série de declarações IF na mesma expressão. Em muitos casos, se deseja comparar as mesmas variáveis (ou expressões), com diferentes valores, e executar pedaços diferentes de código dependendo de qual valor ela é igual. Esta é exatamente a serventia da declaração switch.

Nota: Note que ao contrário de outras linguagens, a declaração continue aplica-se ao switch e age similarmente ao break. Se possuir um switch dentro de um laço, e deseja continuar na próxima iteração do laço externo, utilize continue 2.

Nota:

Note que o switch/case faz comparação frouxa.

No exemplo a seguir, cada bloco de código é equivalente. Um usa uma série de declarações if e elseif, e o outra usa uma declaração switch. A saída é a mesm a em ambos os casos.

Exemplo #1 Estrutura do switch

<?php
// Esta declaração switch:

switch ($i) {
case
0:
echo
"i é igual a 0";
break;
case
1:
echo
"i é igual a 1";
break;
case
2:
echo
"i é igual a 2";
break;
}

// É equivalente a:

if ($i == 0) {
echo
"i é igual a 0";
} elseif (
$i == 1) {
echo
"i é igual a 1";
} elseif (
$i == 2) {
echo
"i é igual a 2";
}
?>

É importante entender como a declaração switch é executada a fim de evitar enganos. A declação switch executa linha por linha (na verdade, declaração por declaração). No início nenhum código é executado. Somente quando uma declaração case é encontrada, cuja expressão avalia um valor que corresponde ao valor do switch, o PHP começará a executar a declaração. O PHP continuará a executar a declaração até o fim do bloco switch, ou até a primeira declaração break encontrada. Se não for escrita uma declaração break ao final da lista de declarações do case, o PHP continuará executando as declarações dos próximos cases. Por exemplo:

<?php
switch ($i) {
case
0:
echo
"i é igual a 0";
case
1:
echo
"i é igual a 1";
case
2:
echo
"i é igual a 2";
}
?>

Neste exemplo, se a variável $i for igual a 0, o PHP executará todos as declarações echo! Se a variável $i for igual a 1, o PHP executará as duas últimas declarações echo. Somente se obterá o comportamento esperado ('i equals 2' será exibido), se $i for igual a 2. Sendo assim, é importante não esquecer as declarações break (mesmo quando se quer evitar, de propósito, sua omissão em certas circunstâncias).

Em uma declaração switch, a condição é avaliada somente uma vez, e o resultado é comparado a cada declaração case. Em uma declaração elseif. a condição é avaliada outra vez. Se a condição for mais complicada que uma simples comparação e/ou está em um laço pequeno, a declaração switch pode ser mais rápida.

A lista de declarações de um case também podem estar vazia, passando o controle da lista de declarações para o próximo case.

<?php
switch ($i) {
case
0:
case
1:
case
2:
echo
"i é menor que 3 mas não é negativo";
break;
case
3:
echo
"i é 3";
}
?>

Um case especial é o default. Este case corresponde a tudo que não foi correspondido pelos outros cases. Por exemplo:

<?php
switch ($i) {
case
0:
echo
"i é igual a 0";
break;
case
1:
echo
"i é igual a 1";
break;
case
2:
echo
"i é igual a 2";
break;
default:
echo
"i não é igual a 0, 1 ou 2";
}
?>

Nota: Múltiplos casos padrões irão emitir um erro E_COMPILE_ERROR.

Nota: Tecnicamente o caso default pode ser listado em qualquer ordem. Ele será usado apenas se nenhum outro caso corresponder. No entando, por conversão, é melhor inseri-lo no fim como a última ramificação.

Se nenhuma ramificação case corresponder, e não existe nenhuma ramificação default, então nenhum código será executado, assim como se nenhuma declaração if fosse verdadeira.

Um valor de caso pode ser dado como uma expressão. No entanto, essa expressão será avaliada de forma isolada, e então será frouxamente comparada com o valor do switch. Isso significa que ela não pode ser usada para avaliações complexas do valor do switch. Por exemplo:

<?php
$alvo
= 1;
$inicio = 3;

switch (
$alvo) {
case
$inicio - 1:
print
"A";
break;
case
$inicio - 2:
print
"B";
break;
case
$inicio - 3:
print
"C";
break;
case
$inicio - 4:
print
"D";
break;
}

// Imprime "B"
?>

Para comparações mais complexas, o valor true pode ser usado como o valor do switch. Ou, alternativamente, if-else em vez do switch.

<?php
$deslocamento
= 1;
$inicio = 3;

switch (
true) {
case
$inicio - $deslocamento === 1:
print
"A";
break;
case
$inicio - $deslocamento === 2:
print
"B";
break;
case
$inicio - $deslocamento === 3:
print
"C";
break;
case
$inicio - $deslocamento === 4:
print
"D";
break;
}

// Imprime "B"
?>

A sintaxe alternativa das estruturas de controle é suportada por switches. Para mais informações, veja Sintaxe alternativa para estruturas de controle.

<?php
switch ($i):
case
0:
echo
"i é igual a 0";
break;
case
1:
echo
"i é igual a 1";
break;
case
2:
echo
"i é igual a 2";
break;
default:
echo
"i não é igual a 0, 1 ou 2";
endswitch;
?>

É possível utilizar o ponto e vírgula ao invés dos dois pontos em um case, como:

<?php
switch($cerveja)
{
case
'amstel';
case
'brahma';
case
'stella';
case
'heineken';
echo
'Boa escolha';
break;
default;
echo
'Por favor faça uma nova seleção...';
break;
}
?>

Veja Também

adicione uma nota

Notas Enviadas por Usuários (em inglês) 6 notes

up
289
MaxTheDragon at home dot nl
12 years ago
This is listed in the documentation above, but it's a bit tucked away between the paragraphs. The difference between a series of if statements and the switch statement is that the expression you're comparing with, is evaluated only once in a switch statement. I think this fact needs a little bit more attention, so here's an example:

<?php
$a
= 0;

if(++
$a == 3) echo 3;
elseif(++
$a == 2) echo 2;
elseif(++
$a == 1) echo 1;
else echo
"No match!";

// Outputs: 2

$a = 0;

switch(++
$a) {
case
3: echo 3; break;
case
2: echo 2; break;
case
1: echo 1; break;
default: echo
"No match!"; break;
}

// Outputs: 1
?>

It is therefore perfectly safe to do:

<?php
switch(winNobelPrizeStartingFromBirth()) {
case
"peace": echo "You won the Nobel Peace Prize!"; break;
case
"physics": echo "You won the Nobel Prize in Physics!"; break;
case
"chemistry": echo "You won the Nobel Prize in Chemistry!"; break;
case
"medicine": echo "You won the Nobel Prize in Medicine!"; break;
case
"literature": echo "You won the Nobel Prize in Literature!"; break;
default: echo
"You bought a rusty iron medal from a shady guy who insists it's a Nobel Prize..."; break;
}
?>

without having to worry about the function being re-evaluated for every case. There's no need to preemptively save the result in a variable either.
up
121
septerrianin at mail dot ru
6 years ago
php 7.2.8.
The answer to the eternal question " what is faster?":
1 000 000 000 iterations.

<?php
$s
= time();
for (
$i = 0; $i < 1000000000; ++$i) {
$x = $i%10;
if (
$x == 1) {
$y = $x * 1;
} elseif (
$x == 2) {
$y = $x * 2;
} elseif (
$x == 3) {
$y = $x * 3;
} elseif (
$x == 4) {
$y = $x * 4;
} elseif (
$x == 5) {
$y = $x * 5;
} elseif (
$x == 6) {
$y = $x * 6;
} elseif (
$x == 7) {
$y = $x * 7;
} elseif (
$x == 8) {
$y = $x * 8;
} elseif (
$x == 9) {
$y = $x * 9;
} else {
$y = $x * 10;
}
}
print(
"if: ".(time() - $s)."sec\n");

$s = time();
for (
$i = 0; $i < 1000000000; ++$i) {
$x = $i%10;
switch (
$x) {
case
1:
$y = $x * 1;
break;
case
2:
$y = $x * 2;
break;
case
3:
$y = $x * 3;
break;
case
4:
$y = $x * 4;
break;
case
5:
$y = $x * 5;
break;
case
6:
$y = $x * 6;
break;
case
7:
$y = $x * 7;
break;
case
8:
$y = $x * 8;
break;
case
9:
$y = $x * 9;
break;
default:
$y = $x * 10;
}
}
print(
"switch: ".(time() - $s)."sec\n");
?>

Results:
if: 69sec
switch: 42sec
up
82
nospam at please dot com
24 years ago
Just a trick I have picked up:

If you need to evaluate several variables to find the first one with an actual value, TRUE for instance. You can do it this was.

There is probably a better way but it has worked out well for me.

switch (true) {

case (X != 1):

case (Y != 1):

default:
}
up
6
me at czarpino dot com
2 years ago
Although noted elsewhere, still worth noting is how loose comparison in switch-case was also affected by the change in string to number comparison. Prior PHP8, strings were converted to int before comparison. The reverse is now true which can cause issues for logic that relied on this behavior.

<?php
function testSwitch($key) {
switch (
$key) {
case
'non numeric string':
echo
$key . ' matches "non numeric string"';
break;
}
}

testSwitch(0); // pre-PHP8, returns '0 matches "non numeric string"'
?>
up
1
php at nospam dot k39 dot se
3 months ago
It is possible to prevent nested switch/match/if blocks by checking for multiple cases at once (just beware that PHP uses loose comparison here).

<?php
$a
= "abc";
$b = "def";

switch ([
$a, $b]) {
case [
"abc", "def"]:
$result = 1;
break;
default:
$result = -1;
}
// $result == 1
?>

If for some cases one of the values is not important, you can use the variable itself:

<?php
$a
= "abc";
$b = "def";

switch ([
$a, $b]) {
case [
"xyz", "def"]:
$result = 1;
break;
case [
$a, "def"]:
$result = 2;
break;
default:
$result = -1;
}
// $result == 2
?>
up
4
j dot kane dot third at gmail dot com
1 year ago
The default case appears to always be evaluated last. If break is excluded from the default case, then the proceeding cases will be reevaluated. This behavior appears to be undocumented.

<?php

$kinds
= ['moo', 'kind1', 'kind2'];

foreach (
$kinds as $kind) {
switch(
$kind)
{
default:
// The kind wasn't valid, set it to the default
$kind = 'kind1';
var_dump('default');

case
'kind1':
var_dump('1');
break;

case
'kind2':
var_dump('2');
break;

case
'kindn':
var_dump('n-th');
break;
}

echo
"\n\n";
}

?>
To Top