I really like the structure of the switch statement compared to using multiple if else.
However some times I want to use the switch statement and have the same value in multiple cases. Can this be done somehow?
switch($fruit) {
case 'apple':
case 'orange':
// do something for both apples and oranges
break;
case: 'apple':
// do something for only apples
break;
case: 'orange':
// do something for only oranges
break;
}
I hope my example show what I intend to do...
No, it cannot. The first case that matches and everything following it until the first break statement or the end of the switch statement will be executed. If you break, you break out of the switch statement and cannot re-enter it. The best you could do is:
switch ($fruit) {
case 'apple':
case 'orange':
...
switch ($fruit) {
case 'apple':
...
case 'orange':
...
}
}
But really, don't. If you need some special action for those two before the individual switch, do an if (in_array($fruit, ['apple', 'orange'])) ... before the switch. Or rethink your entire program logic and structure to begin with.
Create some function and do it like this:
switch($fruit) {
case: 'apple':
apple_and_orange_function();
apple_function();
break;
case: 'orange':
apple_and_orange_function();
orange_function();
break;
}
You cannot match something multiple times, but you can write cascades like these:
switch($fruit) {
case 'apple':
// do something for only apples
case 'orange':
// do something for both apples and oranges
break;
case: 'grapefruit':
// do something for only grapefruits
break;
}
What you want can only be performed with if-else's or deceze's solution though
Related
I have the following if statement (except the final one would be much longer with more values) that I would like to condense.
if ($row['titleId'] == '123' || $row['titleId'] == '456' || $row[){
I would imagine it would end up something like:
if ($row['titleId'] == ('123'||'456'){}
Or would I be better off like this:
$array = ('123','456')
if (in_array($row['titleId'], $array){}
You can use switch for this:
switch ($row['titleId']) {
case '123': case '456': case '789': case '314': case '271':
doSomething();
}
I'd probably still prefer to have each case on a separate line but, if your goal is to reduce the "height" of your code, you can do it as above.
In terms of shortening the code in your comment, which apparently looks like this:
switch($row['titleId']){
case '8216': case '8678': case '8705': case '8216': case '8707':
$rows[$row['titleId']]=array();
break;
case '8214':
$rows['8216'][]=$row['titleId'];
break;
case '8791':
$rows['8678'][]=$row['titleId'];
break;
case '8643':
$rows['8705'][]=$row['titleId'];
break;
case '8666':
$rows['8707'][]=$row['titleId'];
break;
}
you could opt for something like:
$xlat = array('8214'=>'8216', '8791'=>'8678', '8643'=>'8705', '8666'=>'8707');
switch($row['titleId']){
case '8216': case '8678': case '8705': case '8216': case '8707':
$rows[$row['titleId']]=array(); break;
default:
if (array_key_exists($row['titleId'],$xlat)) {
$rows[$xlat[$row['titleId']]][]=$row['titleId'];
}
}
This compresses the common cases by putting them under the control of an associative array. Basically, if the title ID is in the array as a key, its lookup value will be used to affect the correct $rows entry.
Can I write a switch statement like this?
switch ($mood) {
case hungry :
case sad :
echo 'Eat a chocolate';
case sad :
echo 'Call Up your friend';
}
Is this a good practice?
EDIT : Removed the break statement, based on the comment.
It is technically possible to define multiple cases with the same value, but only the first case will get executed. So it's pretty much useless.
From the switch() documentation:
PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement.
Since the first case has a break in it, further cases won't be executed and the code will exit the switch() block.
Consider the following piece of code:
$var = 'sad';
switch ($var) {
case 'sad':
echo 'First';
break;
case 'sad':
echo 'Second';
break;
}
This will output First.
If you want to execute multiple statements if a condition is TRUE, then add them under the same case, like so:
switch ($var) {
case 'sad':
echo 'First';
echo 'Second';
break;
}
I use javascript to send cases to and ajax function. The cases are taken from the link id. For example, if user clicked this link:
<a id="answer-yes-123">click this</a>
The javascript will split the id to 3 part, and send the middle part "yes" to ajax as a case. For most cases, when ajax receives the case, if yes do this if no do that.
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
There's one exception-- a numerical case. If the middle part of the link is a number, I don't know how to make the switching statement. There are potentially unlimited different numbers, I can't make each of them a case, How to make a condition like if(is_int($case)) to work as a case?
In the switch default: case, you can test is_int():
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
default:
// Determine the numeric value however you need to
// is_int(), is_numeric(), preg_match(), whatever...
if (is_int($case)) {
// numeric stuff
}
}
This is a little strange logically, because default: is typically used for the do this if nothing else is met condition. In your case though, if you don't need to further divide the numeric case much it works. Just be sure to comment it clearly in your code so you remember why you did it when you look back on it in six months.
Update after comments:
Since you already used the default:, I believe you can actually use an expression inside a case. This warrants even clearer commenting since it is not a common practice and goes kind of against the purpose of a switch:
switch ($case) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
// This actually works, but is highly weird.
// One of those things I can't believe PHP allows.
// is_int(), is_numeric(), preg_match(), whatever...
case is_int($case):
// Numeric stuff
break;
default:
// default stuff
}
Write the if-statement around the switch.
Something like this comes to my mind:
if (is_int($case)) {
// ...
} else {
switch ($case) {
// ...
}
}
Michael Berkowski's answer is perfect, but if don't want to use default case like this that could work also:
switch (preg_replace('/^[0-9]*$/','numeric',$case)) {
case 'yes' :
$assignment->add();
break;
case 'no' :
$assignment->remove();
break;
case 'numeric' :
$assignment->remove();
break;
default:
//...
break;
}
Use PHP's is_numeric
http://php.net/manual/en/function.is-numeric.php
if (is_numeric($case)) {
// ...
} else {
switch ($case) {
// ...
}
}
This is something that I haven't seen in the PHPdoc for switch() so I'm not sure if it's possible, but I'd like to have a case which is multi-conditional, such as:
switch($this) {
case "yes" || "maybe":
include "filename.php";
break;
...
}
Is this valid syntax/is this even possible with a switch() statement?
Usually you'd just use case fall-through.
switch($this) {
case "yes":
case "maybe":
include "filename.php";
break;
...
}
Is this valid syntax/is this even possible with a switch() statement?
No and no. The expression will be evaluated as ("yes" or "maybe"), which will result in true. switch will then test against that result.
You want to use
case "yes":
case "maybe":
// some code
break;
Should be
switch($this) {
case "yes":
case "maybe":
include "filename.php";
break;
...
}
You can do this with fall-through:
switch ($this) {
case "yes":
case "no":
include "filename.php";
break;
}
Sure, just specify two cases without breaking the first one, like so:
switch($this) {
case "yes":
case "maybe":
include "filename.php";
break;
...
}
If you don't break a case, then any code for that case is run and continues on to execute additional code until the execution is broken. It will continue through all cases below it until it sees a break.
I have multiple switch statements in on one of the pages in order to pass different variables to the URL, as well as different case. I need these different switch statements because I need the different variables.
However, when I put a "default" in one of the switch statements, that default applies to every other switch statement and so when I use the variable of another switch statement in the URL, the default case of that other switch statement will appear on screen, along with the case of this switch statement.
All of my switch statements have one or more cases and I really cannot figure out how to get around this. Please may somebody help me?
Thanks in advance,
Calum.
This might be way off, but I think you need something like this:
if (isset($_POST['myvar'])) {
switch ($_POST['myvar'] {
case 1:
....
break;
default:
....
break;
}
} else if (isset($_POST['myvar2'])) {
switch ($_POST['myvar2'] {
case 1:
....
break;
default:
....
break;
}
}
Does that make sense?
make sure that you have a "break;" statement at the end of each of your cases, and that the default case is the last one. like this:
switch ($var) {
case 1: // do stuff 1;
break;
case 3: // do stuff 2;
break;
// ...
default: // do default stuff
}