PHP 8.4.2 Released!

switch

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

La sentencia switch es similar a una serie de sentencias IF en la misma expresión. En muchas ocasiones, es posible que se quiera comparar la misma variable (o expresión) con muchos valores diferentes, y ejecutar una parte de código distinta dependiendo de a que valor es igual. Para esto es exactamente la expresión switch.

Nota: Cabe señalar que a diferencia de algunos otros lenguajes, la sentencia continue se aplica a switch y actúa de manera similar a break. Si se tiene un switch dentro de un bucle y se desea continuar a la siguiente iteración de del ciclo exterior, se utiliza continue 2.

Nota:

Tener en cuenta que switch/case hace comparaciones flexibles.

Historial de cambios
Versión Descripción
7.0.0 Múltiples casos predeterminados (default) emitirán un error de tipo E_COMPILE_ERROR.

Los dos ejemplos siguientes son dos formas diferentes de escribir lo mismo, uno con una serie de sentencias if y elseif, y el otro usando la sentencia switch:

Ejemplo #1 Estructura switch

<?php
if ($i == 0) {
echo
"i es igual a 0";
} elseif (
$i == 1) {
echo
"i es igual a 1";
} elseif (
$i == 2) {
echo
"i es igual a 2";
}

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

Ejemplo #2 Estrutura switch permite el uso de strings

<?php
switch ($i) {
case
"manzana":
echo
"i es una manzana";
break;
case
"barra":
echo
"i es una barra";
break;
case
"pastel":
echo
"i es un pastel";
break;
}
?>

Es importante entender cómo la sentencia switch es ejecutada con el fin de evitar errores. La sentencia switch ejecuta línea por línea (en realidad, sentencia por sentencia). Al principio, ningún código es ejecutado. Solo cuando se encuentra una sentencia case cuya expresión se evalúa a un valor que coincida con el valor de la con un valor que coincide con el valor de la expresión switch, PHP comienza a ejecutar la sentencias. PHP continúa ejecutando las sentencias hasta el final del bloque switch, o hasta la primera vez que vea una sentencia break. Si no se escribe una sentencia break al final de la lista de sentencias de un caso, PHP seguirá ejecutando las sentencias del caso siguiente. Por ejemplo:

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

Aquí, si $i es igual a 0, PHP ejecutaría todas las sentencias echo! Si $i es igual a 1, PHP ejecutaría las últimas dos sentencias echo. Se obtendría el comportamiento esperado (se mostraría 'i es igual a 2') sólo si $i es igual a 2. Por lo tanto, es importante no olvidar las sentencias break (aunque es posible que se desee evitar proporcionarlas a propósito bajo determinadas circunstancias).

En una sentencia switch, la condición es evaluada sólo una vez y el resultado es comparado con cada una de las sentencias case. En una sentencia elseif, la condición es evaluada otra vez. Si la condición es más complicada que una simple comparación y/o está en un bucle estrecho, un switch puede ser más rápido.

La lista de sentencias para un caso también puede estar vacía, lo cual simplemente pasa el control a la lista de sentencias para el siguiente caso.

<?php
switch ($i) {
case
0:
case
1:
case
2:
echo
"i es menor que 3 pero no negativo";
break;
case
3:
echo
"i es 3";
}
?>

Un caso especial es el default. Este caso coincide con cualquier cosa que no se haya correspondido por los otros casos. Por ejemplo:

<?php
switch ($i) {
case
0:
echo
"i es igual a 0";
break;
case
1:
echo
"i es igual a 1";
break;
case
2:
echo
"i es igual a 2";
break;
default:
echo
"i no es igual a 0, 1 ni 2";
}
?>

La sintaxis alternativa para las estructuras de control es compatible con los switch. Para obtener más información, consulte Sintaxis alternativa de estructuras de control.

<?php
switch ($i):
case
0:
echo
"i es igual a 0";
break;
case
1:
echo
"i es igual a 1";
break;
case
2:
echo
"i es igual a 2";
break;
default:
echo
"i no es igual a 0, 1 ni 2";
endswitch;
?>

Es posible utilizar un punto y coma en lugar de dos puntos después de un caso como:

<?php
switch($beer)
{
case
'tuborg';
case
'carlsberg';
case
'heineken';
echo
'Buena elección';
break;
default;
echo
'Por favor haga una nueva selección...';
break;
}
?>

add a note

User Contributed Notes 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
4 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
2 years 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