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.switch
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
switch
Референца за `control-structures.switch.php` со подобрена типографија и навигација.
switch
(PHP 4, PHP 5, PHP 7, PHP 8)
На switch изјавата е слична на серија од IF изјави на истиот израз. Во многу случаи, можеби ќе сакате да ја споредите истата променлива (или израз) со многу различни вредности и да извршите различен дел од кодот во зависност од тоа на која вредност се едначи. Ова е токму она што е
switch изјавата за.
Забелешка: Забележете дека за разлика од некои други јазици, continue изјавата се применува на
switchи делува слично наbreak. Ако иматеswitchвнатре во циклус и сакате да продолжите на следната итерација на надворешниот циклус, користетеcontinue 2.
Забелешка:
Забележете дека switch/case прави лабаво споредување.
Во следниот пример, секој блок од код е еквивалентен. Едниот користи серија од if and
elseif изјави, а другиот
switch изјава. Во секој случај, излезот е ист.
Пример #1 switch structure
<?php
// This switch statement:
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
// Is equivalent to:
if ($i == 0) {
echo "i equals 0";
} elseif ($i == 1) {
echo "i equals 1";
} elseif ($i == 2) {
echo "i equals 2";
}
?>
Важно е да се разбере како се извршува switch
изјавата за да се избегнат грешки. Во
switch изјавата се извршува ред по ред (всушност, изјава по изјава). На почетокот, не се извршува никаков код. Дури кога ќе се најде case изјава чиј израз се проценува на вредност што одговара на вредноста на
switch изразот, PHP започнува да ги извршува изјавите. PHP продолжува да ги извршува изјавите до крајот на switch блокот, или првпат кога ќе види break изјава. Ако не напишете
break изјава на крајот од списокот со изјави на случајот, PHP ќе продолжи да ги извршува изјавите на следниот случај. На пример:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
Овде, ако $i е еднакво на 0, PHP би ги извршил сите изјави за ехо! Ако $i е еднакво на 1, PHP би ги извршил последните две изјави за ехо. Би го добиле очекуваното однесување ('i е еднакво на 2' би било прикажано) само ако $i е еднакво на 2. Така, важно е да не заборавите break изјави (иако можеби сакате да избегнете да ги давате намерно под одредени околности).
изјава, условот се оценува само еднаш и резултатот се споредува со секој switch изјава. Во
case изјава, условот повторно се оценува. Ако вашиот услов е покомплициран од едноставно споредување и/или е во тесна јамка, а elseif
може да биде побрз. switch Листата на изјави за случај може да биде и празна, што едноставно ја пренесува контролата во листата на изјави за следниот случај.
случај. Овој случај одговара на сè што не било одговарано од другите случаи. На пример:
<?php
switch ($i) {
case 0:
case 1:
case 2:
echo "i is less than 3 but not negative";
break;
case 3:
echo "i is 3";
}
?>
Посебен случај е default Повеќе стандардни случаи ќе предизвикаат
<?php
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
default:
echo "i is not equal to 0, 1 or 2";
}
?>Забелешка: Технички
E_COMPILE_ERRORerror.
Забелешка: случајот може да биде наведен во било кој ред. Тој ќе се користи само ако ниту еден друг случај не одговара. Сепак, по конвенција е најдобро да се постави на крајот како последна гранка.
defaultАко ниту еден
гранка не одговара, и нема case гранка, тогаш нема да се изврши никаков код, исто како да не е ниту една default
изјава вистинита. if Вредноста на случајот може да се даде како израз. Сепак, тој израз ќе се оцени сам по себе и потоа ќе се спореди лабаво со вредноста на прекинувачот. Тоа значи дека не може да се користи за сложени проценки на вредноста на прекинувачот. На пример:
(PHP 4, PHP 5, PHP 7, PHP 8)
<?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;
}
// Prints "B"
?>
Вредноста на случајот може да се даде како израз. Сепак, тој израз ќе се процесира самостојно и потоа ќе се спореди лабаво со вредноста на прекинувачот. Тоа значи дека не може да се користи за сложени евалуации на вредноста на прекинувачот. На пример: true За посложени споредби, вредноста if-else може да се користи како вредност на прекинувачот. Или, алтернативно, 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;
}
// Prints "B"
?>блокови наместо Алтернативен синтакс за контролни структури.
<?php
switch ($i):
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
default:
echo "i is not equal to 0, 1 or 2";
endswitch;
?>Алтернативниот синтаксен за контролни структури е поддржан со прекинувачи. За повеќе информации, видете
<?php
switch($beer)
{
case 'tuborg';
case 'carlsberg';
case 'stella';
case 'heineken';
echo 'Good choice';
break;
default;
echo 'Please make a new selection...';
break;
}
?>Белешки од корисници 6 белешки
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: 42secIt 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
?>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:
}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"'
?>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";
}
?>