-4

I'm having trouble with a switch case conidtion.

Why in the following scenario:

$category = "A";
$offer = "none";
$discount = "none";

For the following code:

switch (TRUE) {

case ($category == 'A') : / #1

    $msg = "hello"; 

case ($offer == 'special') : / #2

        $id = "123"; 

case ($discount == '50D') : / #3

        $id = "999";


break;

echo $id;

}

I get output of 999 for id, even though #2 and #3 are not fullfilled?

EDIT:

Cases such as $offer == 'special' are private cases of the general case which is $category == 'A'. That's why I want the function to go in this order. if switch/case is not appropriate, what shall I use?

rockyraw
  • 1,125
  • 2
  • 15
  • 36
  • why all the downvotes? isn't that how the function should work? – rockyraw Jan 02 '16 at 17:03
  • I think that's because people don't clearly understand what the problem is. – Yang Jan 02 '16 at 17:04
  • Don't start from the middle. Start from the beginning when describing your problem. – Yang Jan 02 '16 at 17:05
  • Possible duplicate of [Multiple Cases in Switch:](http://stackoverflow.com/questions/68578/multiple-cases-in-switch) – PAlphen Jan 02 '16 at 17:10
  • Read more about the PHP [switch statement](http://php.net/manual/en/control-structures.switch.php). This is how it was designed to work, 40 years ago, in `C`; `PHP` and a lot of other languages copied the behaviour of `switch` statement from `C`. – axiac Jan 02 '16 at 17:11
  • 2
    Use, conditionals, not a `switch`. Specifically, `PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case`. - http://php.net/manual/en/control-structures.switch.php – chris85 Jan 02 '16 at 17:12
  • Possible duplicate of [Switch Statement returns incorrect results](http://stackoverflow.com/questions/34446189/switch-statement-returns-incorrect-results) – chris85 Jan 02 '16 at 17:15
  • @chris85 do you mean "IF" condition? I got into a mess with them in [this thread](http://stackoverflow.com/questions/34566942/how-to-consolidate-various-if-conditions-into-a-final-result), maybe you can recommend something over there? – rockyraw Jan 02 '16 at 17:21
  • Let's just go with your current thread here. There's a lot happening in that other thread if `$offer == 'special'` and `$discount == '50D'` what should `$id` be? – chris85 Jan 02 '16 at 17:30
  • @chris85 `999`, the idea is that `special` is a private case of `category A` and `50D` is a private case of `special` – rockyraw Jan 02 '16 at 17:33
  • Oh so if a and special and 50d set `999` if just special set `123` and if neither just leave the message? – chris85 Jan 02 '16 at 17:39
  • small correction: `a+special+50=999`,`a+special=123`,only `A`= just message / do nothing. and I plan to have a category such as `B` with it's own set of cases. – rockyraw Jan 02 '16 at 17:42
  • Take a look at the updated answer below. I think that should give you a starting point. – chris85 Jan 02 '16 at 17:44
  • I've removed my answer and moved it to your other thread. @Barmar answered the question of why the `switch` doesn't work, which is a separate question than your other thread. – chris85 Jan 02 '16 at 18:14

2 Answers2

3

Once switch finds a matching case, it just executes all the remaining code until it gets to a break statement. None of the following case expressions are tested, so you can't have dependencies like this. To implement sub-cases, you should use nested switch or if statements.

switch ($category) {
case 'A':
    $msg = 'hello';
    if ($offer == 'special') {
        $id = '123';
    } elseif ($discount == '50D') {
        $id = '999';
    }
    break;
...
}
echo $id;

The fallthrough feature of case without break is most often used when you have two cases that should do exactly the same thing. So the first one has an empty code with no break, and it just falls through.

switch ($val) {
case 'AAA':
case 'bbb':
    // some code
    break;
...
}

It can also be used when two cases are similar, but one of them needs some extra code run first:

switch ($val) {
case 'xxx':
    echo 'xxx is obsolete, please switch to yyy';
case 'yyy':
    // more code
    break;
...
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • alright, so in what instance would anyone would ever want to use a `switch` without `break` between two different cases, if all other cases don't mean anything? – rockyraw Jan 02 '16 at 17:19
  • One example `case 'A': case 'a':`. So both capital and lowercase fall into same group. – chris85 Jan 02 '16 at 17:20
  • @rockyraw I've added some examples where fallthrough might be used. – Barmar Jan 02 '16 at 17:25
0

This is how a switch-case statement works. It goes through all the casees once one condition was met, as long as there is no break. You can read up on it in the manual here: PHP switch.

If you want to stop the execution of the switch at the end of an case, just add a break; statement.

ArSeN
  • 5,133
  • 3
  • 19
  • 26
  • I don't want to stop the execution. Since the other cases such as `$offer == 'special'` are private cases of the general case which is `$category == 'A'` – rockyraw Jan 02 '16 at 17:11
  • 1
    It doesn't test the other cases when it falls through. Once it finds a matching case, it just executes everything until it gets to `break`. – Barmar Jan 02 '16 at 17:12
  • 1
    What's that *"private cases"*? Use an inner `switch` or `if` statements if you want to check the values of `$offer` and `$discount` only when `$category` matches. – axiac Jan 02 '16 at 17:13
  • I was advised to use switch/case in [my original thread](http://stackoverflow.com/questions/34566942/how-to-consolidate-various-if-conditions-into-a-final-result), so what do you recommend considering that other thread? – rockyraw Jan 02 '16 at 17:17
  • @rockyraw IMHO, that style of using `switch` is perverse. It works, but it's confusing. – Barmar Jan 02 '16 at 17:20
  • what would be the best practice to achieve the goal of my original thread? using IF conditions also caused me some mess. – rockyraw Jan 02 '16 at 17:23
  • @rockyraw When you have a "global" condition that is a pre condition, then why don't use create code block that is only executed if that condition is true, and then put the switch (or more ifs) inside of it? This does not sound like mess to me, but rather like a reasonable approach – ArSeN Jan 02 '16 at 17:34