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 statement is similar to a series of
if statements on the same expression. In situations where it is necessary to compare the same variable or expression with many different values, and execute a different piece of code depending on which value it equals, the switch statement is often more convenient and easier to read.
Забелешка:
Забележете дека за разлика од некои други јазици, continue изјавата се применува на
switchand acts similarly tobreak. Ако иматеswitchвнатре во циклус и сакате да продолжите на следната итерација на надворешниот циклус, користетеcontinue 2.
Забелешка:
Note that switch/case does a лабаво споредување.
Во следниот пример, секој блок од код е еквивалентен. Едниот користи серија од if and
elseif изјави, а другиот
switch изјава. Во секој случај, излезот е ист.
Пример #1 switch structure
<?php
$i = 1;
// This switch statement:
switch ($i) {
case 0:
echo "i equals 0\n";
break;
case 1:
echo "i equals 1\n";
break;
case 2:
echo "i equals 2\n";
break;
}
// Is equivalent to:
if ($i == 0) {
echo "i equals 0\n";
} elseif ($i == 1) {
echo "i equals 1\n";
} elseif ($i == 2) {
echo "i equals 2\n";
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
i equals 1 i equals 1
Важно е да се разбере како се извршува switch
изјавата за да се избегнат грешки. Во
switch изјавата се извршува ред по ред (всушност, изјава по изјава). На почетокот, не се извршува никаков код. Дури кога ќе се најде case изјава чиј израз се проценува на вредност што одговара на вредноста на
switch изразот, PHP започнува да ги извршува изјавите. PHP продолжува да ги извршува изјавите до крајот на switch блокот, или првпат кога ќе види break изјава. Ако не напишете
break изјава на крајот од списокот со изјави на случајот, PHP ќе продолжи да ги извршува изјавите на следниот случај. На пример:
<?php
$i = 1;
switch ($i) {
case 0:
echo "i equals 0\n";
case 1:
echo "i equals 1\n";
case 2:
echo "i equals 2\n";
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
i equals 1 i equals 2
Овде, ако $i е еднакво на 0, PHP би ги извршил сите изјави за ехо! Ако $i е еднакво на 1, PHP би ги извршил последните две изјави за ехо. Би го добиле очекуваното однесување ('i е еднакво на 2' би било прикажано) само ако $i е еднакво на 2. Така, важно е да не заборавите break изјави (иако можеби сакате да избегнете да ги давате намерно под одредени околности).
изјава, условот се оценува само еднаш и резултатот се споредува со секој switch изјава. Во
case изјава, условот повторно се оценува. Ако вашиот услов е покомплициран од едноставно споредување и/или е во тесна јамка, а elseif
statement, the condition is evaluated again. If your condition is more complicated than a simple comparison and/or is in a tight loop, a switch Листата на изјави за случај може да биде и празна, што едноставно ја пренесува контролата во листата на изјави за следниот случај.
случај. Овој случај одговара на сè што не било одговарано од другите случаи. На пример:
<?php
$i = 1;
switch ($i) {
case 0:
case 1:
case 2:
echo "i is less than 3 but not negative";
break;
case 3:
echo "i is 3";
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
i is less than 3 but not negative
Посебен случај е default Повеќе стандардни случаи ќе предизвикаат
<?php
$i = 4;
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";
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
i is not equal to 0, 1 or 2
Забелешка:
Multiple default cases will raise an
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;
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
B
Вредноста на случајот може да се даде како израз. Сепак, тој израз ќе се процесира самостојно и потоа ќе се спореди лабаво со вредноста на прекинувачот. Тоа значи дека не може да се користи за сложени евалуации на вредноста на прекинувачот. На пример: true За посложени споредби, вредноста if-else blocks can be used instead of 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;
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
B
блокови наместо Алтернативен синтакс за контролни структури.
<?php
$i = 1;
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;Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
i equals 1
It's possible to use a semicolon instead of a colon after a case. As of PHP 8.5.0, this syntax is deprecated.
<?php
$beer = 'cola';
switch($beer)
{
case 'tuborg';
case 'carlsberg';
case 'stella';
case 'heineken';
echo 'Good choice';
break;
default;
echo 'Please make a new selection...';
break;
}Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 6 Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 7 Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 8 Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 9 Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead in script on line 12 Please make a new selection...
Претходната порака за грешка DEPRECATED HTTP одговорни за одговор
Дневник на промени
| Верзија | = NULL |
|---|---|
| 8.5.0 |
The alternate syntax using a semicolon after case е укинат.
|
Белешки од корисници 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";
}
?>