switch statement without break
Solution 1
Fallthrough was an intentional design feature for allowing code like:
switch ($command) {
case "exit":
case "quit":
quit();
break;
case "reset":
stop();
case "start":
start();
break;
}
It's designed so that execution runs down from case to case.
default
is a case like any other, except that jumping there happens if no other case was triggered. It is not by any means a "do this after running the actual selected case" instruction. In your example, you could consider:
switch($param) {
case "created":
if(!($value instanceof \DateTime))
throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
break;
case "Creator":
if(!($value instanceof \Base\User)) {
throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");
}
break;
}
$this->$param = $value;
The rule of thumb here is, if it doesn't depend on the switch, move it out of the switch.
Solution 2
Because that's how it's done in C.
Solution 3
Perhaps this will enlighten you:
Jump Table Switch Case question
Solution 4
I don't really see what you want.
- If you want to run the default stuff in all cases, just put it after the switch.
- If you want to run the default stuff only in the "created" case and in the default case, swap the position of the "created" and "Creator" sections and put a break after the first.
- If you want that code to only run if Creator or created matches, then get rid of the switch statement and use an if/else OR use a flag and a following if statement.
All the tools are there.
Solution 5
In PHP 8 we have match
, similar with switch
expression but is significantly shorter:
- it doesn't require a break statement
- it can combine different arms into one using a comma
- it returns a value, so you only have to assign value once
An example:
$message = match ($statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};
Here's its switch
equivalent:
switch ($statusCode) {
case 200:
case 300:
$message = null;
break;
case 400:
$message = 'not found';
break;
case 500:
$message = 'server error';
break;
default:
$message = 'unknown status code';
break;
}
reference : https://stitcher.io/blog/php-8-match-or-switch
Rene Terstegen
Updated on June 14, 2022Comments
-
Rene Terstegen almost 2 years
How come a case option in a switch statement that does not contain a break automatically forwards to a next case without check?
try { switch($param) { case "created": if(!($value instanceof \DateTime)) throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param"); case "Creator": if(!($value instanceof \Base\User)) { throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator"); } default: $this->$param = $value; break; } } catch(Exception $e) { echo $e->getMessage(); }
If the param is "created" it will do the check in the created-case, which is good. When the check is succesful, I want the code to continue to the default option, that's why there is no break;. But instead it continues to "Creator" while $param != "Creator"!
I do know how to solve this (just add the default code in my case "created"), but I don't like to repeat that code too often. My actual question is: Why does it continue with the "Creator" case while the case is not "Creator".
-
Morfildur over 13 yearsI would add that - while fall-through is sometimes usefull - it's better to not use it where both cases do something instead of just falling through (Good:
case "created": case "creator": case "something_else": do_stuff();
Bad:case "created": do_stuff(); case "creator": do_Second_stuff(); case "something_else": do_remaining_stuff();
) -
Rene Terstegen over 13 yearsIt's not about what I want, it is about why a switch statement is working like this.
-
Victor Nicollet over 13 years@dbemerlin: it's indeed quite dangerous, though acceptable if the cases are short or in languages which support explicit fallthrough (like C#).
-
Hammerite over 13 yearsBest is to add a comment to say fallthrough is intentional.
-
caveman over 13 yearsI apologize that I misunderstood the question. History is the answer. Like most anything in programming, somebody said so. This is how they said. There's some history there (basically that C started it), but that is the syntax.