PHP 8.3.21 Released!

switch

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

La instrucción switch equivale a una serie de instrucciones if. En numerosas ocasiones, se necesitará comparar la misma variable (o expresión) con un gran número de valores diferentes, y ejecutar diferentes partes de código según el valor al que sea igual. Esto es exactamente para lo que sirve la instrucción switch.

Nota: Téngase en cuenta que, a diferencia de otros lenguajes, la estructura continue se aplica a las estructuras switch y se comporta de la misma manera que break. Si se tiene un switch dentro de un bucle, y se desea continuar hasta la siguiente iteración del bucle externo, se debe utilizar continue 2.

Nota:

Téngase en cuenta que switch/case provoca una comparación amplia.

En el siguiente ejemplo, cada bloque de código es equivalente. Uno utiliza una serie de instrucciones if y elseif, y el otro una instrucción de tipo switch. En cada caso, la salida es la misma.

Ejemplo #1 Instrucción switch

<?php
// Este switch:

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

// Equivale a:

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

Es importante entender que la instrucción switch ejecuta cada una de las cláusulas en orden. La instrucción switch se ejecuta línea por línea. Al principio, no se ejecuta ningún código. Solo cuando se encuentra una instrucción case cuya expresión se evalúa a un valor que coincide con el valor de la expresión switch, PHP ejecuta entonces las instrucciones correspondientes. PHP continúa ejecutando las instrucciones hasta el final del bloque de instrucciones del switch, o bien hasta que encuentra la instrucción break. Si no se puede utilizar la instrucción break al final de la instrucción case, PHP continuará ejecutando todas las instrucciones que siguen. Por ejemplo :

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

En este ejemplo, si $i es igual a 0, PHP ejecutará todas las instrucciones que siguen ! Si $i es igual a 1, PHP ejecutará las dos últimas instrucciones. Y solo si $i es igual a 2, se obtendrá el resultado esperado, es decir, la visualización de "i igual 2". Por lo tanto, es importante no olvidar la instrucción break (aunque es posible que se omita en ciertas circunstancias).

En un comando switch, una condición se evalúa solo una vez, y el resultado se compara con cada case. En una estructura elseif, las condiciones se evalúan en cada comparación. Si la condición es más complicada que una simple comparación, o bien forma parte de un bucle, switch será más rápido.

La lista de comandos de un case puede estar vacía, en cuyo caso PHP utilizará la lista de comandos del caso siguiente.

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

Un caso especial es default. Este caso se utiliza cuando todos los otros casos han fallado. Por ejemplo :

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

Nota: Varios casos default generarán un error de nivel E_COMPILE_ERROR.

Nota: Técnicamente, el caso default puede ser colocado en cualquier posición. Solo se utilizará si ningún otro caso coincide. Sin embargo, por convención, es preferible colocarlo al final.

Si ningún case coincide, y no hay un default, entonces no se ejecutará ningún código, al igual que si ninguna instrucción if fuera verdadera.

Un valor de case puede ser dado en forma de expresión. Sin embargo, esta expresión será evaluada sola, y luego comparada de manera aproximada con el valor del switch. Esto significa que no puede ser utilizada para evaluaciones complejas del valor del switch. Por ejemplo :

<?php
$target
= 1;
$start = 3;

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

// Muestra "B"
?>

Para comparaciones más complejas, el valor true puede ser utilizado como valor de switch. O, alternativamente, bloques if-else en lugar de switch.

<?php
$offset
= 1;
$start = 3;

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

// Muestra "B"
?>

La sintaxis alternativa para esta estructura de control es la siguiente : (para más información, ver sintaxis alternativas).

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

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

<?php
switch($beer)
{
case
'leffe';
case
'grimbergen';
case
'guinness';
echo
'Buena elección';
break;
default;
echo
'Por favor, haga una elección...';
break;
}
?>

Ver también

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
9 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