switch

switch구문은 연속적인 같은 표현식을 갖는 연속적인 IF구문과 비슷하다. 많은 경우, 하나의 변수(또는 표현식)으로 다른 많은 값과 비교할 필요가 있으며, 그 값이 동일한 코드의 파편들을 수행할 필요가 생기게 된다. 정확히 이런 목적을 위해 switch구문이 사용된다.

Note: 다른 언어와는 달리 continue문은 switch문에서 사용할수 있고, break문과 비슷하게 동작한다. 루프 내에 switch문을 포함하고 있고 바깥 루프의 다음 반복문으로 진행하고 싶다면 continue 2를 사용한다.

Note:

switch/case는 느슨한 비교를 하는 점에 주의하십시오.

다음 예제 코드들은 같은 일을 서로 다르게 표현한 것입니다. 하나는 ifelseif문을 사용한 것이고, 다른 하나는 switch문을 사용했습니다:

Example #1 switch 구조

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

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

Example #2 문자열을 사용하는 switch 구조

<?php
switch ($i) {
case 
"apple":
    echo 
"i는 apple";
    break;
case 
"bar"
    
echo "i는 bar";
    break;
case 
"cake":
    echo 
"i는 cake";
    break;
}
?>

실수하지 않기 위해 switch문이 어떻게 동작하는지 이해할 필요가 있다. switch문은 한줄씩 수행된다 (실제는, 한구문씩). 처음에는 아무 코드도 수행되지 않는다. switch 표현의 값과 일치하는 값을 가진 case 구문을 발견했을 때, PHP는 그 구분을 실행합니다. PHP는 switch블록의 끝부분이 될때까지, 또는 break문와 첫번째 조우를 할때까지 구문을 계속 수행해 간다. 만약 각 case 구문 목록의 끝부분에 break문을 쓰지않는다면 PHP는 다음 case문으로 계속 진행하게 된다. 예를 들면 다음과 같다:

<?php
switch ($i) {
case 
0:
    echo 
"i는 0과 같다";
case 
1:
    echo 
"i는 1과 같다";
case 
2:
    echo 
"i는 2와 같다";
}
?>

여기에서, $i가 0이라면, PHP는 모든 echo문을 실행합니다! $i가 1이라면, PHP는 마지막 두 echo문을 실행합니다. $i가 2일 때만, 원하는 동작('i는 2와 같다' 표시)을 합니다. 따라서, break을 잊어서는 안됩니다. (어떤 경우에는 일부러 빠트릴 수 있어도, 잊지 마십시오)

switch구문에서, 조건문은 오직 한번만 평가되고 각 case문에서 결과가 비교되어진다. elseif문에서는 조건문은 다시 평가된다. 조건문이 한번 이상의 비교가 필요한 복잡한 것이거나 거친(tight) 루프안에 있다면 switch문 좀 더 빠를것이다.

case에 대한 구문 목록은 비어있을수 있다. 이것은 단순히 다음 case문으로 제어권을 넘겨줄 뿐이다.

<?php
switch ($i) {
case 
0:
case 
1:
case 
2:
    echo 
"i는 3보다 작지만 음수는 아닙니다.";
    break;
case 
3:
    echo 
"i는 3";
}
?>

특별한 case가 바로 default case문이다. 이것은 다른 case문과 모두 조건이 맞지 않을때의 경우를 위한 것입니다. 예를 들면:

<?php
switch ($i) {
case 
0:
    echo 
"i는 0과 같다";
    break;
case 
1:
    echo 
"i는 1과 같다";
    break;
case 
2:
    echo 
"i는 2와 같다";
    break;
default:
    echo 
"i는 0, 1, 2 어느것도 아니다";
}
?>

case의 표현식은 정수나 부동소수점 수와 문자열같은 단순형으로 평가되는 어던 표현식도 될수 있다. 여기에 단순형으로 재참조(dereference)되지 않는 배열이나 객체를 사용할수는 없다.

switch문을 위한 제어 구조의 대체 문법이 지원된다. 더 자세한 정보는 제어 구조의 대체 문법을 참고.

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

case 뒤에 세미콜론 대신 콜론을 쓸 수 있습니다:

<?php
switch($beer)
{
    case 
'tuborg';
    case 
'carlsberg';
    case 
'heineken';
        echo 
'Good choice';
    break;
    default;
        echo 
'Please make a new selection...';
    break;
}
?>

add a note add a note

User Contributed Notes 6 notes

up
287
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
115
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
76
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
3
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
2
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";
}

?>
up
-2
GeorgNation
1 year ago
You can wrap up the case/break block with a curly braces:

$x = 2;

switch ($x)
{
    case 2: {
        echo '2 entrypoint';
        break;
    }
   
    default: {
        echo 'default entrypoint';
        break;
    }
}
To Top