PHP 8.1.31 Released!

switch

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

switch deyimi, aynı ifade içersinde yer alan bir dizi IF deyimine benzer. Birçok durumda, aynı değişkeni (ya da ifadeyi) birden çok değerle karşılaştırmak ve her karşılaştırmanın sonucunu ayrı bir kod parçası çalıştırarak değerlendirmek istersiniz. İşte bu, switch deyiminin varlık sebebidir.

Bilginize: Başka bazı dillerden farklı olarak, continue deyimi switch ile uygulanabilir ve break ile benzerlik gösterir. Bir döngü içerisinde switch kullandıysanız ve kodun yürütülmesine dıştaki döngünün sonraki yinelemeden devam etmesini istiyorsanız, continue 2 kullanabilirsiniz.

Bilginize:

switch ve case gevşek karşılaştırma yapar.

Aşağıdaki iki örnek aynı şeyi yazmanın iki farklı yolunu göstermektedir. Birincisi bir dizi if ve elseif deyiminin kullanımını, ikincisi ise switch deyiminin kullanımını örneklemektedir:

Örnek 1 - switch yapısı

<?php
// Bu switch deyimi:

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

// bunlara eşdeğerdir:

if ($i == 0) {
echo
"i eşittir 0";
} elseif (
$i == 1) {
echo
"i eşittir 1";
} elseif (
$i == 2) {
echo
"i eşittir 2";
}

?>

Hatalardan kaçınmak için switch deyiminin nasıl çalıştığını anlamak önemlidir. switch deyimi satır satır ele alınır (aslında deyim deyim). Başlangıçta, hiçbir kod çalıştırılmaz. Yalnızca switch ifadesiyle birlikte verilen değer ile uyuşan case deyimi bulunduğunda PHP ilgili deyimleri çalıştırmaya başlar. PHP switch bloğu sonlanana kadar ya da ilk break deyimi ile karşılaşıncaya kadar çalışmasına devam eder. Bir case bloğunun sonuna break koymazsanız, PHP sonraki case deyiminden kodları çalıştırmaya devam eder. Örnek:

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

Burada, $i 0'a eşit ise, PHP tüm echo deyimlerini çalıştıracaktır! $i 1'e eşit ise, PHP son iki echo deyimini çalıştıracaktır! Beklediğiniz sonucu ('i eşittir 2' metninin görüntülenmesi) yalnızca $i 2'ye eşitse almanız mümkün olacaktır. Bu durumun oluşmaması için, break deyimini kullanmayı unutmamanız önemlidir (yine de, bazı durumlarda break deyimini kullanmak istemeyebilirsiniz).

Bir switch deyiminde, koşul yalnızca bir defa sorgulanır ve sonuç her bir case deyimi ile karşılaştırılır. Bir elseif deyiminde ise, koşul tekrar sorgulanır. Kullanmak istediğiniz koşul basit bir karşılaştırma işleminden daha karmaşıksa ve/veya bir döngü içerisindeyse, switch kullanmak daha hızlı olabilir.

case bloğu kod içermeyebilir ve amacı yalnızca denetimi bir sonraki case bloğuna geçirmek olabilir.

<?php
switch ($i) {
case
0:
case
1:
case
2:
echo
"i 3'ten küçüktür ama negatif değildir";
break;
case
3:
echo
"i eşittir 3";
}
?>

default durumu özel bir durumdur. Bu durum diğer hiçbir case ile uyuşmayan değerler için kullanılır ve en sonda yer almalıdır. Örneğin:

<?php
switch ($i) {
case
0:
echo
"i eşittir 0";
break;
case
1:
echo
"i eşittir 1";
break;
case
2:
echo
"i eşittir 2";
break;
default:
echo
"i ne 0, ne 1 ne de 2'ye eşittir";
}
?>

Bilginize: Çok sayıda default kullanımı E_COMPILE_ERROR hatasını tetikler.

Bilginize: Teknik olarak default en sonda olmak zorunda değildir, herhangi bir yerde olabilir. Yanızca başka bir eşleşme olmazsa kullanılır. Ancak, geleneksel olarak, son dal olarak en sona yerleştirmek en iyisidir.

Hiçbir case eşleşmezse ve default dalı da yoksa tıpkı doğrulanmayan if deyiminde olduğu gibi hiçbir kod çalıştırılmaz.

case değeri bir ifade olarak belirtilebilir. Ancak, bu ifade kendi başına değerlendirilecek ve daha sonra switch değeri ile gevşek bir şekilde karşılaştırılacaktır. Yani, switch değeri karmaşık değerlendirmeler için kullanılamaz. Örnek:

<?php
$hedef
= 1;
$ilk = 3;

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

// "B" basar.
?>

Daha karmaşık karşılaştırmalarda true değeri switch değeri olarak kullanılabilir. Veya, switch yerine if-else deyimleri kullanılabilir.

<?php
$konum
= 1;
$ilk = 3;

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

// "B" basar.
?>

İki noktalı sözdizimi switch deyimi için de desteklenmektedir. Daha fazla bilgi için, Denetim yapıları için diğer sözdizimi bölümünü inceleyebilirsiniz.

<?php
switch ($i):
case
0:
echo
"i eşittir 0";
break;
case
1:
echo
"i eşittir 1";
break;
case
2:
echo
"i eşittir 2";
break;
default:
echo
"i ne 0, ne 1 ne de 2'ye eşittir;
endswitch;
?>

case’ten sonraki iki nokta yerine aşağıdaki gibi deyim sonunda noktalı virgül kullanmak da mümkündür:

<?php
switch($içecek)
{
case
'su';
case
'süt';
case
'ayran';
echo
'İyi seçim';
break;
default;
echo
'Lütfen yeniden seçiniz...';
break;
}
?>

Ayrıca Bakınız

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