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

up
214
MaxTheDragon at home dot nl
7 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
32
septerrianin at mail dot ru
1 year 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
60
nospam at please dot com
18 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
35
mmxg at shaw dot ca
11 years ago
In reply to lko at netuse dot de

Just so others know whom may not, that's because PHP does automatic type conversion if a string is evaluated as an integer (it sees the 2 in '2string' so when compared like if ('2string' == 2), PHP sees if (2 == 2) ).

I just tested it, but if you go:

<?php

$string
="2string";

switch(
$string)
{
    case (string)
1:
        echo
"this is 1";
        break;
    case (string)
2:
        echo
"this is 2";
        break;
    case
'2string':
        echo
"this is a string";
        break;
}

?>

The output will be "this is a string" and if you change $string to "2" it will again be "this is 2".

Just in case that may help anyone who may run into that problem.
up
44
lko at netuse dot de
11 years ago
Attention if you have mixed types of value in one switch statemet it can make you some trouble

<?php

$string
="2string";

switch(
$string)
{
    case
1:
        echo
"this is 1";
        break;
    case
2:
        echo
"this is 2";
        break;
    case
'2string':
        echo
"this is a string";
        break;
}

?>

The swich-statement will halt on 'case 2'

Answer: this is 2
up
11
havar at henriksen dot nu
16 years ago
Remember, that you also could use functions in a switch.
For example, if you need to use regular expressions in a switch:

<?php
$browserName
= 'mozilla';
switch (
$browserName) {
  case
'opera':
    echo
'opera';
  break;
  case (
preg_match("/Mozilla( Firebird)?|phoenix/i", $browserName)?$browserName:!$browserName):
    echo
"Mozilla or Mozilla Firebird";
  break;
  case
'konqueror':
    echo
'Konqueror';
  break;
  default:
    echo
'Default';
  break;
}
?>

or you could just use a regular expression for everything:

<?php
$uri
= 'http://www.example.com';
switch (
true) {
  case
preg_match("/$http(s)?/i", $uri, $matches):
    echo
$uri . ' is an http/https uri...';
  break;
  case
preg_match("/$ftp(s)?/i", $uri, $matches):
    echo
$uri . ' is an ftp/ftps uri...';
  break;
  default:
    echo
'default';
  break;
}
?>
up
15
manicdepressive at mindless dot com
15 years ago
Be careful if distinguishing between NULL and (int)0.  As implied in the above documentation, the case statements are equivalent to the '==' operator, not the '===' operator, so the following code did not work as i expected:

<?php
$mixed
= 0;
switch(
$mixed){
   case
NULL: echo "NULL";  break;
   case
0: echo "zero";  break;
   default: echo
"other"; break;
}
?>

Instead, I may use a chain of else-ifs.  (On this page, kriek at jonkreik dot com states that "in most cases [a switch statement] is 15% faster [than an else-if chain]" but jemore at m6net dotdot fr claims that when using ===, if/elseif/elseif can be 2 times faster than a switch().)

Alternatively, if i prefer the appearance of the switch() statement I may use a trick like the one nospam at please dot com presents:

<?php
$mixed
= 0;
switch(
TRUE){
   case (
NULL===$mixed): //blah break;
  
case (0   ===$mixed): //etc. break;
}
?>

code till dawn! mark meves!
up
12
Hayley Watson
11 years ago
Something not mentioned in the documentation itself, and only touched on momentarily in these notes, is that the default: case need not be the last clause in the switch.
<?php
for($i=0; $i<8; ++$i)
{
    echo
$i,"\t";
    switch(
$i)
    {
    case
1: echo "One"; break;
    case
2:
    default: echo
"Thingy"; break;
    case
3:
    case
4: echo "Three or Four"; break;
    case
5: echo "Five"; break;
    }
    echo
"\n";
}
?>
Outputs what you'd expect, namely
0       Thingy
1       One
2       Thingy
3       Three or Four
4       Three or Four
5       Five
6       Thingy
7       Thingy
with case 2 and the default both producing the same result ("Thingy"); strictly speaking, the case 2 clause is completely empty and control just falls straight through. The same result could have been achieved with
<?php
switch($i)
{
    case
1: echo "One"; break;
    case
3:
    case
4: echo "Three or Four"; break;
    case
5: echo "Five"; break;
    default: echo
"Thingy"; break;
}
?>
But if "case 2" represented a fairly common case (other than "everything else"), then it would be better to declare it explicitly, not only because it saves time by not having to test EVERY other case first  (in the current example, PHP finds 'case 2' in the first switch in two tests, but in the second switch it has to make four tests before giving up and going with the default) but also because someone (perhaps yourself in a few months' time) will be reading the code and expecting to see it handled. Listing it explicitly aids comprehension
up
7
richard
10 years ago
Just a word of warning about using switch don't try and compare variables that contain numbers with strings like so:

<?php
$i
=0;

switch(
$i)
{
    case
'TEST': print "Test";break;
    case
0: print "0";break;
}
?>

The output will be: Test and not 0.
up
6
lchanady at gmail dot com
9 years ago
Something fairly simple (and maybe obvious) that I didn't see mentioned is that the default case WILL be executed even if the switched variable does not exist or is undefined.

For example:

<?php

$a
= "abc";
$b = "def";

switch(
$c){
    case
"a":
        echo
"a";
        break;
    case
"b":
        echo
"b";
        break;
    default:
        echo
"default";
        break;
}

?>

Will output: default

Even though $c was never declared or defined, the default case will still be executed rather than PHP throwing an error.
up
3
Anonymous
4 years ago
Please note that PHP won't throw any error/warning if your `switch` utilizes more than one `default` - in such case it will just jump to the first one.

Also note that you (for unknown reason for me) are allowed to use semicolons `;` along colon `:` for `case` and `default` entries:

<?php

switch($foo) {
   case
0:    // colon
       
...
   break;

   case
1;    // semicolon is fine
       
...
   break;
}
up
6
Anonymous
7 years ago
Rewriting the function (to be three times faster) provided by [stever at ashomecare dot com 07-Sep-2007 09:11] and demonstrating points that others have made:

<?php
function getChineseZodiac($year){

    switch (
$year % 12) :
        case 
0: return 'Monkey'// Years 0, 12, 1200, 2004...
       
case  1: return 'Rooster';
        case 
2: return 'Dog';
        case 
3: return 'Boar';
        case 
4: return 'Rat';
        case 
5: return 'Ox';
        case 
6: return 'Tiger';
        case 
7: return 'Rabit';
        case 
8: return 'Dragon';
        case 
9: return 'Snake';
        case
10: return 'Horse';
        case
11: return 'Lamb';
    endswitch;
}

echo
getChineseZodiac(2016);
?>
up
3
Keil
10 years ago
As follow-up to ben dot lancaster at holler dot co dot uk's post:

'continue' ends the switch, not the case, just as it would with any other flow control. Think of it as putting the execution pointer right before the ending accolade (that is, the }) because that is essentially what happens. In the case of a for loop, this would cause the iteration clause to execute, and if applicable, the loop to begin again. However, switches do not loop, which is why (as noted above, in the manual!) a continue statement essentially acts as a break when within a switch.
up
1
2mareks (at) gmail (dot) com
12 years ago
In reply to earlier comment, "switch"- I found this to be one of the best ways to interpret 'actions'. Simply create a new instance of Handler_action before including any content source files. This is a highly stripped version of the class.

The real one I created handles (and secures) input for $_GET and $_POST, creates a 'permission' array that only allows certain actions to be called by non-admins, and creates handy little diagnostic messages that can be displayed upon redirecting.

On that note, the beauty in this class really shines in the simple redirect. You wont be left with ugly URLs like, "http://www.domain.com/path/to/script.php?action=blah&var1=123". Rather, you will be left with something like "http://www.domain.com/path/to/script.php"- helps protect some of the site by not showing any vulnerabilities in URLs.

Also, this class keeps all actions organized neatly by directly passing $_GET vars to the actions through function parameters.

<?php
 
class Handler_action {
    function
__construct( ){
     
//Add code here to secure attacks through $_GET or use $_POST
     
$action = $_GET["action"];
 
     
//$actions_index conventions:
      //'action_name' => array( 'arg1', 'arg2', 'etc', ['/redirect/to/path' | NULL ] )
     
$actions_index = array(
       
'create' => array( $_GET['newVar1'], $_GET['newVar2'], '/home.php' ),
       
'edit' => array( $_GET['id'], $_GET['otherVar'], '/home.php' ),
       
'delete' => array( $_GET['id'], '/other_script.php' )
      );
             
      if(
$action && array_key_exists( $action, $actions_index ) ){
       
$redirect_path = array_pop( $actions_index[$action] );
       
call_user_func_array( array( &$this, $action ), $actions_index[$action] );
        if(
$redirect_path )
         
header( "Location: http://www.domain.com{$redirect_path}" );
      }
    }

   
//being defining actions now
   
function create( $new_var1, $new_var2 ){
 
     
//code...
 
   
}
    function
edit( $id, $other_var ){
 
     
//code...
 
   
}
    function
delete( $id ){
 
     
//code...
 
   
}
  }
?>
up
0
Manucyan
4 months ago
Some tests:

switch ('aaaaa') {
        default         : echo "DEFAULT TOP 1"; break;
        default         : echo "DEFAULT TOP 2"; break;
       
        case 'aaaaa': echo "CASE TOP 1"; break;
        case 'aaaaa': echo "CASE TOP 2"; break;
       
        default         : echo "DEFAULT BOTTOM 1"; break;
        default         : echo "DEFAULT BOTTOM 2"; break;
       
        case 'aaaaa': echo "CASE BOTTOM 1"; break;
        case 'aaaaa': echo "CASE BOTTOM 2"; break;
}
//return ------>  CASE TOP 1

switch ('SOMETHING_THAT_DOESN_T_EXIST') {
        default         : echo "DEFAULT TOP 1"; break;
        default         : echo "DEFAULT TOP 2"; break;
       
        case 'aaaaa': echo "CASE TOP 1"; break;
        case 'aaaaa': echo "CASE TOP 2"; break;
       
        default         : echo "DEFAULT BOTTOM 1"; break;
        default         : echo "DEFAULT BOTTOM 2"; break;
       
        case 'aaaaa': echo "CASE BOTTOM 1"; break;
        case 'aaaaa': echo "CASE BOTTOM 2"; break;
}
//return ------>  DEFAULT BOTTOM 2

    Some observations:
    - no errors if several identical boxes or defaultes
    - the last defect takes over
    - the first of the boxes takes the hand
    - we can put the default at the top (indeed sometimes it's more intuitive)
up
1
chernyshevsky at hotmail dot com
17 years ago
Be very careful when you're using text strings as cases. If the variable supplied to switch() is an integer, the cases would be converted to integer before the comparison is made (usually to zero). The following snippet prints "hello".

<?php
$a
= 0;
switch(
$a) {
case
'Hello': echo "Hello";
break;
}
?>
up
0
druellan at sfidastudios dot com
5 years ago
Be careful if you have mixed types of values in the switch statement. Explicitly cast your variables where possible to avoid mismatch:

<?php
$var
= 0;

// This match case #1
// switch ( $var )

// This works as expected
switch ( (string)$var )
{
  case
"0string":
    echo
"0string match";
    break;
}
?>
up
-1
theimp at iinet dot net dot au
9 years ago
It's easy to abuse the switch syntax to do some very useful things. As this example will show, the possibilities can go beyond even Duff's Device-style craziness (not that this example is nearly as clever as Duff's Device, but it demonstrates how you can do certain things other than simply the increment/decrement/assignment that's possible in C).

Fundamentally, this works mostly due to the fact that, from the point of view of the assembler/interpreter, a switch block is hardly any different from a bunch of GOTO labels and  if()  evaluations. But, like an  if() evaluation, the line of a case: statement is evaluated as an expression. So, in this case, we can perform an assignment and match the result of that assignment, because the return value of an assignment is the data that was assigned (and not the value of the variable it was assigned to, as you might expect).

So far, this is not actually amazing, even if it is a bit unintuitive. From a language point-of-view, it would be the same as an  if($var = "string")  statement which is using an assignment (=) rather than a comparison (==) operator. When you look at the pre-processing optimization, because a normal assignment of $var = "string" will always equal "string", it makes sense to have the result of that expression simply be equal to the right side of the expression (the right side is used rather than the left to let the assembler/interpreter work faster, on account of how they traditionally simply change the memory location for the assigned variable rather than copy the memory around unnecessarily).

Where this becomes more interesting is where, in PHP, you have language constructs that behave like functions but are used like statements. An  $array[] = "string"  expression is actually a language construct that just happens to behave a lot like a function, but you use it in the same way that you use an assignment expression, and like an expression, it always evaluates to the right side of the expression; in this case,  "string"  and not  array() .

The assembler/interpreter can't use the right side of the expression as a shortcut for the result of a function, so you can't use functions in this way in a case statement. You also can't get around this limit on calling functions from the case line by using variable functions, because they are used in the same way as functions.

But imagine what you could do with other language constructs, like eval() or include() !

Consider the following:

<?php
function flavor($type = null)
{
    switch (
$type) {
       
/* Note the isolation of break; statements and the fact that default: is at the top */
       
default:
           
$type = null;
        case
$array[] = "chocolate":
            if (
$type != null) {
               
$array = array($type);
                break;
            }
        case
$array[] = "strawberry":
            if (
$type != null) {
               
$array = array($type);
                break;
            }
        case
$array[] = "vanilla":
            if (
$type != null) {
               
$array = array($type);
                break;
            }
    }
    if ( (
count($array) != 1) ) {
        return
"Flavors available: " . implode(", ", $array);
    } else {
        return
"Flavor selected: " . implode(", ", $array);
    }
}

echo
flavor() . "<br>";
/* Flavors available: chocolate, strawberry, vanilla */

echo flavor("banana") . "<br>";
/* Flavors available: chocolate, strawberry, vanilla */

echo flavor("chocolate") . "<br>";
/* Flavor selected: chocolate */
?>

What makes this example useful is that you don't need a variable somewhere that contains the available options (even within the function itself), so to support new options, you only ever have to change the code to add the new option - you don't need to update some variable somewhere that controls whether or not it works or whether or not people can tell that there's a new option.
up
-2
info at maisuma dot jp
4 years ago
If you want to avoid numeric compare for numeric strings in switch statement, try prepending something non-numeric.

e.g.
<?php
$val
='2';
switch(
$val){
case
'2.0' : echo '2.0!??'; break;
case
'2' : echo '2.'; break;
}
?>
echoes '2.0!??' ; while prepended version
<?php
$val
='2';
switch(
'#' . $val){
case
'#2.0' : echo '2.0!??'; break;
case
'#2' : echo '2.'; break;
}
?>
echoes '2.'.
up
-3
sedativchunk at gmail dot com
10 years ago
Not sure if this has been posted or not, but I found the switch statement useful for finding ranges of data.

This script creates web 2.0 style links in different font sizes (popular on blogs) using a randomizer and switch statement. I used links from within a database for a mod I made for a Simple Machines forums, but this example uses arrays for links if you wanted to add your own custom links:
<?php
// Create set of links
$link = array();
$link[] = '<a href="whatever.html">page 1</a>';
$link[] = '<a href="whatever.html">page 2</a>';
$link[] = '<a href="whatever.html">page 3</a>';
$link[] = '<a href="whatever.html">page 4</a>';
$link[] = '<a href="whatever.html">page 5</a>';
$link[] = '<a href="whatever.html">page 6</a>';
$link[] = '<a href="whatever.html">page 7</a>';
$link[] = '<a href="whatever.html">page 8</a>';

// Create loop to display links
for($i = 0; $i < count($link); ++$i)
{
   
// Create randomizer
    // Use switch statement to find font size
   
$randomizer = rand(1,50);
    switch(
$randomizer)
    {
    case (
$randomizer <= 20):
   
$font_size = "11";
    break;

    case (
$randomizer <= 30):
   
$font_size = "16";
    break;

    case (
$randomizer <= 40):
   
$font_size = "18";
    break;

    case (
$randomizer <= 50):
   
$font_size = "20";
    break;
    }

   
// Display the link
   
echo '<span style="font-size: ' .$font_size. ';">' .$link[$i]. '</span>&nbsp;&nbsp;';

// Loop the next link
}
?>

Using this type of range randomizer is useful for game development and it can be useful on the web too, for things where you don't want to use a randomizer just for things like (1-5) where you wanted a more then likely result for one thing over another. The switch statement saves from writing spaghetti code if statements.
up
-2
hamiltont at gmail dot com
10 years ago
Example of default NOT included as the last item

<?php
switch(5) {
  case
1:
    echo
"1";
    break;
  case
2:
  default:
    echo
"2, default";
    break;
  case
3;
    echo
"3";
    break;
}
?>

Outputs '2,default'

very useful if you want your cases to be presented in a logical order in the code (as in, not saying case 1, case 3, case 2/default) and your cases are very long so you do not want to repeat the entire case code at the bottom for the default

Hamy
up
-1
rmunn at pobox dot com
16 years ago
In answer to njones at fredesign dot com, what you're seeing is the way the switch statement is supposed to work. The switch statement evaluates the cases, top to bottom, until it finds the first one that matches the value being switch()ed on. So, for example, if you had:

<?php
switch(2) {
case
1: echo "One\n"; break;
case
2: echo "Two\n"; break;
case
3: echo "Three\n"; break;
case
2: echo "Two again\n"; break;
}
?>

Only "Two" would get echoed. "Two again" would NOT get echoed, because once the first case matches, the rest of them do NOT get evaluated. As soon as a matching case is found, the statements starting at that case get executed until the first break, then control flows out the bottom of the switch block.
up
-2
Anonymous
7 years ago
Regarding [php_net at mcdragonsoftware dot com 17-Jun-2011 09:53]; the elegant function and syntax provided for an "inline switch" statement is more readable and about 25% faster than this alternative (that uses existing builtin functions), which produces the same result:

<?php echo array_pop(array_slice(array( 'rock', 'paper', 'scissors' ), --$roll, 1)); ?>
up
-4
mar dot czapla at gmail dot com
11 years ago
<?php
   
/* script 1  */
   
$foo = "not a number";
    switch(
false)
    {
        case
"1":    {    $foo = "1";    break;    }
        case
"2":    {    $foo = "2";    break;    }
        default:    {   
$foo = "0";    }
    }
   
    echo
$foo;    // will produce "not a number"
   
    /* script 2  */
   
$foo = "not a number";
   
$arr = array("not a number"); // 1 element only !
   
switch($arr[1])    // element $foo[1] doesn't defined
   
{
        case
"1":    {    $foo = "1";    break;    }
        case
"2":    {    $foo = "2";    break;    }
        default:    {   
$foo = "0";    }
    }
   
    echo
$foo;    // will produce "not a number" ( not 0 ! )
   
    /* script 3  */
   
$foo = "not a number";
   
$arr = array("not a number"); // 1 element only !
   
switch($arr[1]?$arr[1]:"1")    // element $foo[1] doesn't defined
   
{
        case
"1":    {    $foo = "1";    break;    }
        case
"2":    {    $foo = "2";    break;    }
        default:    {   
$foo = "0";    }
    }
   
    echo
$foo;   
   
// will produce :
    // 1 if $arr[1] isn't set
    // 1 if $arr[1]=1
    // 2 if $arr[1]=2
    // 0 if none of above
?>
up
-2
paz at spiralon dot com
17 years ago
In case : ) it helps someone, I was able to clean up some hairball code by using nested switches (didn't see it mentioned here).  Thanks to all those who are writing examples - I love this site!

<?php
$string_match
="second";
switch (
$string_match) {
case
"first":
case
"second":
case
"third":
    print
"<H3>Something for all three</H3><br>";
    switch (
$string_match) {
      case
"first":
      print
"something for first only";
      break;
      case
"second":
      case
"third":
      print
"something for the other two";
      break;
    }
break;
default:
print
"<H3>no match</H3>";
}
?>
up
-3
cretz
11 years ago
Haven't seen it mentioned here, but at least in my version (PHP 5.2.5) and I'm sure all of PHP 5, the switch statement is a great way to check type safe enumerates that are otherwise missing in the PHP language. Example:

<?php

class WannabeEnum {
   
/**
     * @var WannabeEnum
     */
   
public static $FOO;
   
/**
     * @var WannabeEnum
     */
   
public static $BAR;
   
/**
     * @var WannabeEnum
     */
   
public static $FOOBAR;
    private
$_ordinal;
    public function
__construct($ordinal) {
       
$this->_ordinal = $ordinal;
    }
}
WannabeEnum::$FOO = new WannabeEnum(1);
WannabeEnum::$BAR = new WannabeEnum(2);
WannabeEnum::$FOOBAR = new WannabeEnum(3);

function
testSwitch(WannabeEnum $wannabeEnum) {
    switch(
$wannabeEnum) {
        case
WannabeEnum::$FOO:
            echo(
'Foo!' . PHP_EOL);
            break;
        case
WannabeEnum::$BAR:
            echo(
'Bar!' . PHP_EOL);
            break;
        default:
            echo(
'Default!' . PHP_EOL);
    }   
}
testSwitch(WannabeEnum::$FOO);
testSwitch(WannabeEnum::$FOOBAR);
?>

Outputs:

Foo!
Default!

Don't forget it uses loose comparisons!
up
-4
mr at bwsolution dot de
9 years ago
"loose comparison" means that switch won't check the type.
switch will only compare values:
<?php
if('a string' == 0) echo 'a string is 0' . PHP_EOL;
if(
'a string' === 0) echo 'but you will never see this' . PHP_EOL;
switch(
0){
    case
'a string': echo 'a string' . PHP_EOL;
    case
'another string': echo 'another string' . PHP_EOL;
}

if(
'a string' == true) echo 'a string is TRUE' . PHP_EOL;
if(
'a string' === true) echo 'but you will never see this' . PHP_EOL;
switch(
true){
    case
'a string': echo 'a string' . PHP_EOL;
    case
'another string': echo 'another string' . PHP_EOL;
}
?>

will output:
a string is 0
a string
another string
a string is TRUE
a string
another string
up
-2
php dot net dot 1 at yogelements dot com
15 years ago
Declaring a variable (actually an array) as static w/in a switch{} spun my wool for a while:
don't:
<?
function ss() {
    switch ("bug") {
        case "bug" :
           static $test = "xyz";
           break;
        default :
           static $test = "abc";
    }
echo $test;
}
ss(); //abc
?>
do:
<?
function tt() {
    static $test;
    switch ("fix") {
        case "fix" :
           $test = "xyz";
           break;
        default :
           $test = "abc";
    }
echo $test;
}
tt(); // xyz
?>
up
-2
shawn at evilest dot net
16 years ago
You can also nest switch statements inside case statements:

<?php
  
// Set argument handlers
   
$argv = explode(",", urldecode(getenv('QUERY_STRING')));
   
$argc = array_shift($argv);
   
$argd = array_shift($argv);
   
$arge = array_shift($argv);
?>

   // Begin switching

<?php
   
switch ($argc) {
        case
'home': {
             print(
'This is $argc, home case.');
            break;
        }
        case
'subsection': {
                switch (
$argd) {
                     case
'links': {
                            switch(
$arge) {
                                case
'display': {
                                print(
'This is $arge, subsection,links,display case.');
                                break;
                                }
                           }
                    }
                }
        }
    }
?>
up
-3
gmgiles at pacbell dot net
15 years ago
Did you know that switch() and case() can also accomodate things like basic math calculations and counter incrementing? They do. In this example, I use a switch statement (which is inside of a while loop) to alternate the background color of a table row. It gives me a cool spool-printer-paper effect.

<?php
$rows_per_color
= 5// change bgcolor every 5 rows
switch($ctr++) {
    case
0:
       
$bgcolor = "#ffffff";
        break;
    case (
$rows_per_color):
       
$bgcolor = "#ff0000";
        break;               
    case (
$rows_per_color * 2):
       
$bgcolor = "#ffffff";
       
$ctr = 1;
        break;       
}
?>

As you can see, I increment $ctr by 1 in the switch() itself, and the final case() does a simple calculation. Simple, but powerful. [Remember, the above example is inside of a while() loop... each time it iterates, switch increments $ctr.]
up
-4
Anonymous
7 years ago
Switch usage for make some actions with all of cases

<?php
$out
= ' ';
for (
$i=1;$i<10:$i++) {
   switch (
$i) {
      case
true: $out .= 'test_';
      case
1:
      case
2:
      case
3: $out .= $i;
      default:
$out .= ' ';
   }
}
echo
$out;
?>

That sample out:

" test_1 test_2 test_3 "
up
-2
x@x
18 years ago
often you will have to perform multiple actions in sequence, but this sequence must be broken once one of them detects a stop condition (such as an error, when validating form request variables).
One way is to use:

if (check1()
&& check2()
&& check3()
) valid();
else error();

But when the sequence is long and must reordered, this can be errorprone because not all line of check have the same syntax (imagine that you want to comment one of them).

Another way is to rewrite it as:

check1() and
check2() and
check3() and
...
valid() or
error();

The above syntax does not fit well when the valid() code must be several statements.
An alternative syntax can be:

switch (false) {
case check1():
case check2():
case check3():
  error();
  break;
default:
  valid();
}

This last equivalent sample show you that each case expressions is evaluated, until one of them evaluates to a value equal (==) to the switch expression. Above, the error() code will only be called if one of the check evaluates to false. And the valid() code will only be evaluated only if the switch reach the default, which means that none of the above check returned false...
up
-2
jon
15 years ago
In response to the entry by "kriek at jonkriek dot com", I think you would probably be better of doing this:
<?php
   
// ensure $_GET['go'] is set, an integer, and not 0
    // then, set nav number; default to 1
   
$nav = ( isset($_GET['go']) && (intval($_GET['go']) == $_GET['go']) && $_GET['go'] ) ?
       
intval($_GET['go']) : 1;

   
// format navigation string and include
   
include(sprintf("Page%02d.php",$nav));   
?>

... as oppposed to the switch setup you recommended, which is limited to the number of cases you specify...
up
-2
theonly dot mcseven at gmx dot net
16 years ago
working a bit around with it I found out that it is not possible to
compare the variable with two different values in one step like this
(system running a w2k server, apache2.0.43 & php430):

<?php
switch ($myvar) {
case (
"foo" || "bar"): //do something
break;
case (
"other"): //do another thing
break;
default:
}
?>

rather use:

<?php
switch ($myvar) {
case (
"foo"):
case (
"bar"): //do something
break;
case (
"other"): //do another thing
break;
default:
}
?>
up
-6
Anonymous
12 years ago
I could have used a swich for this, but I found that using the array was much faster.

    $action = $_GET['action'];

    $pages = array
    (
      'edit'   => './edit.php',
      'search' => './search.php'
    );

    if(strlen($pages[$action]) > 0)
    {
      require $pages[$action];
    }
    else
    {
      require './default.php';
    }
To Top