9

Will the default of a switch statement get evaluated if there's a matching case before it?

ex:

switch ($x) {
  case ($x > 5): print "foo";
  case ($x%2 == 0): print "bar";
  default: print "nope";
}

so for x = 50, you'd see foo and bar, or foo and bar and nope?

6
  • 6
    Did you try running this code? Commented Aug 10, 2012 at 14:49
  • 2
    If there is no case match, the default case will be executed. Commented Aug 10, 2012 at 14:50
  • 2
    FYI case ($x > 5) evaluates to case 1: or case true:. Commented Aug 10, 2012 at 14:51
  • 2
    Without break your code will try to match all conditions. With break it'll stop at the 1st match. Commented Aug 10, 2012 at 14:59
  • 2
    Without breaks in your code, it will execute the first matching case and every case thereafter. Commented Aug 10, 2012 at 15:46

4 Answers 4

9

Yes, if there is no "break", then all actions following the first case matched will be executed. The control flow will "falls through" all subsequent case, and execute all of the actions under each subsequent case, until a break; statement is encountered, or until the end of the switch statement is reached.

In your example, if $x has a value of 50, you would actually see "nope".

Note that switch is actually performing a simple equality test, between the expression following the switch keyword, and each expression following the case keyword.

Your example is unusual, in that it will only display "foo" when $x has a value of 0. (Actually, when $x has a value of 0, what you would see would be "foo bar nope".)

The expression following the case keyword is evaluated, which in your case, example return a 0 (if the conditional test is false) or a 1 (if the conditional test is true). And it's that value (0 or 1) that switch will compare to $x.

Sign up to request clarification or add additional context in comments.

Comments

6

Will the default of a switch statement get evaluated if there's a matching case before it?

In most cases it shouldn't, because you would often have breaks in there. However in your case it would also go to the default.

Also please try to prevent to do those single line stuff (for readability):

$x = 10;

switch (true) {
  case ($x > 5):
      print "foo";

  case ($x%2 == 0):
      print "bar";

  default:
      print "nope";
}

Will print foobarnope. So to answer your question: yep :-)

1 Comment

prints foobarnope. Soon as any case is true, all following cases, including default, up to a break (or end of switch) will run. codepad.viper-7.com/sjHYeZ
3

That's not how switches work.

According to the manual:

The switch statement is similar to a series of IF statements on the same expression. In many occasions, you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals to. This is exactly what the switch statement is for.

An evaluation like

case ($x > 5):

simply equates to

case true:

or

case false:

depending on the value of $x because ($x > 5) is an EVALUATION, not a VALUE. Switches compare the value of the parameter to see if it equates to any of the cases.

switch($x) {
    case ($x > 5): // $x == ($x > 5)
        echo "foo";
        break;
    case ($x <= 5): // $x == ($x <= 5)
        echo "bar"
        break;
    default:
        echo "default";
        break;
}

The comparison in the above code is equivalent to

if ($x == ($x > 5)) {
    echo "foo";
} elseif ($x == ($x < 5)) {
    echo "bar";
} else {
    echo "five";
}

which (when $x == 50) is equivalent to

if ($x == true) {
    echo "foo";
} elseif ($x == false) {
    echo "bar";
} else {
    echo "five";
}

which is equivalent to

if (true) { // $x == true is the same as saying "$x is truthy"
    echo "foo";
} elseif (false) {
    echo "bar";
} else {
    echo "five";
}

IF, however, you used your switch statement as it is intended to be used (to compare the parameter to concrete values):

switch ($x) {
    case 50:
        echo "foo ";
    case 30:
        echo "bar ";
    default:
        echo "foo-bar";
}

and $x == 50, your output would be

foo bar foo-bar

due to the fact that you have no break in your cases.

Had you added the break keyword to the end of each case, you would only execute the code for that specific case.

switch ($x) {
    case 50:
        echo "foo ";
        break;
    case 30:
        echo "bar ";
        break;
    default:
        echo "foo-bar";
        break;
}

Output:

foo 

12 Comments

No, you didn't. Read what you wrote. You said that you can't use switches "like that", and you are wrong - you can, and nothing prevents anyone from doing so. Posting a half-correct answer is horrible, someone will walk in and read what you wrote and think you were right when you weren't.
The OP's switch statement perfectly valid. Having evaluations in cases is perfectly valid and highly desirable code. Your answer only shows one type of use of the statement.
@Matt - there's nothing wrong behind the logic you're trying to explain, what's wrong is your explanation of the switch statement. Switch statement behaves exactly like an if statement. You can compare values in order to get a true or false. switch is just a convenience invented so one doesn't have to type 100 if/else combinations and nest the code to oblivion.
@buggabill I'm not so sure it's highly desirable but it is valid. My point was that it shouldn't be used in that fashion unless it's fully understood why it's being used.
@Matt, one line though I don't agree with. "The output for the above code would always be default unless $x == 1". This untrue. In the comparison $x==($x > 5) for example, there is an implicit conversion of $x to boolean which will evaluate to true as long as $x!=0. If $x=0, that statement will actual return true as $x will be false and $x>5 is false so you get false==false. If $x=1 to 5, the statement returns false as any non 0 number converts to boolean true. so the statement becomes true==false. any number above 5 the statement will return true true == true.
|
2

It would have been easier to try it yourself.

But anyway, if you don't use break in a case, all the the cases following it will be executed (including the default).

1 Comment

It's true that there are places other than stackoverflow to figure out the answers to questions, but when we do that no one gets to collect rep ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.