'or' operator inside switch PHP [duplicate] - php

This question already has answers here:
How to add multiple condition cases inside Switch method?
(3 answers)
Closed 9 years ago.
Well, I think this is kinda weird but I would like to know if I can use the 'or' operator inside a switch something like this:
$pet = 'cat';
switch($pet)
case 'cat' or 'Cat':
echo 'Is a cat';
break;
case 'dog' or 'Dog':
echo 'Is a dog';
break;
default:
echo 'There is no pet';
break;
};
I tried it yesterday and somehow I think it worked, maybe, today I tried something similar but it didn't worked, I would like to know if there's a way to do something like this, and if there's a way to compare two values inside a case.
Thank's.

I'm not a hundred percent sure as I didn't use PHP for a while, but you should be able to write something like that:
$pet = 'cat';
switch ($pet)
{
case 'cat':
case 'Cat':
echo 'Is a cat';
break;
case 'dog':
case 'Dog':
echo 'Is a dog';
break;
default:
echo 'There is no pet';
break;
};
Alternatively, you can use a method like strtolower($pet) before you run the switch case, so that you only have to test one thing at a time.
$pet = 'cat';
$testedString = strtolower($pet);
switch ($testedString)
{
case 'cat':
echo 'Is a cat';
break;
case 'dog':
echo 'Is a dog';
break;
default:
echo 'There is no pet';
break;
};

Related

Please explain why PHP switch case is always executing case 0 in this code

Can someone please explain why the case "a" is never reached in below code and why it will always execute case 0
switch ("a") {
case 0:
echo "0";
break;
case "a": // never reached because "a" is already matched with 0
echo "a";
break;
}
PHP, like JavaScript or Perl, is a loosely-typed language and will attempt to guess what you want to do. In this case, it changed your string to the closest integer it could find, which is zero. In other words, "a" == 0 is a true statement in PHP.
More on this topic can be found in the PHP documentation. I suggest you typecast the value in the switch statement, or replace it with an if/elseif/else construct.
As of PHP 8.0, this behaviour has changed and now the integer value will always be changed to a string before comparison between the two types. Strictly typing and comparing your variables remains the recommended practice, however.
You can not used mix-cases in a switch statement as PHP will interpret the meaning of what you mean.
In layman's terms, it will try to find the 'value of "a"' which is not defined to the processor, and hence is 0 in this case.
Same will go for the code below:
<?php
$x = "a";
switch($x)
{
case "c":
echo "c";
break;
case 1:
echo "1";
break;
case 0:
echo "0";
break;
case "a":
echo "a";
break;
case false:
echo "false";
break;
default:
echo "def";
break;
}
?>
Documentation is available at PHP.net
The reason for this is because switch uses a loose comparison ==
That said:
if ("a" == 0) // TRUE
if ("a" == true) // TRUE
Pretty much anything else will evaluate to false. (except "a" == "a")
So, if you have the need to compare against both strings and integers, you should just convert to string for the comparison.
//$var = "a";
$var = 0;
$var = strval($var);
switch ($var) {
case '0':
echo "0";
break;
case 'a':
echo "a";
break;
}
The variable type used on case() should be same type used in switch().
<?php
switch ("a") {
case "0":
echo "0";
break;
case "a": // never reached because "a" is already matched with 0
echo "a";
break;
}
For integer type:
<?php
switch (1) {
case 0:
echo 0;
break;
case 1: // never reached because "a" is already matched with 0
echo 1;
break;
}

php switch statement returns invalid output

php switch statement returns invalid output :
$cond = "Night";
switch($cond){
case "Morning":
case "Night":
$name = "Good";
case "Morning" :
echo $name." Morning";
break;
case "Night" :
echo $name." Night";
break;
}
output : Good Morning
Expected Good Night
Edit (after reading replies) :
Thanks for answers.
I didn't get a clear answer.
I know i can use another statement like if else.
But logically the code should work correctly(I think).
because there's no break after 2 first cases .
but why when execution reaches to case "Morning" , the condition is true while isn't true in real?
You could do it slightly differently - as there is always going to be a good you could do this:
$cond = "Night";
$pre='Good ';
switch($cond){
case "Morning" : echo $pre." Morning"; break;
case "Night" : echo $pre." Night"; break;
}
As you didn't add break first case - execution continues and breaks after
echo $name." Morning";
But even if you add break statement for the first case - you won't reach last case:
case "Night" :
echo $name." Night";
break;
as execution already out of switch-block.
So you have to write some other code with another logic. Simple one is:
$cond = "Night";
switch($cond){
case "Morning":
case "Night":
echo "Good" . $cond;
break;
}
The switch construct is always a bit of a risk when you do not specify a break, as execution will just continue to the next cases without testing those conditions.
As stated in the docs, I emphasise in bold:
It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. 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.
So, to be clear: PHP does not verify case conditions any more once it has started executing statements inside a case. Without a break, it will just continue with the statements of the next cases without verifying the case conditions. And so it goes from case to case, executing all statements until it finds a break or the end of the switch.
So the following code:
switch (1) {
case 1:
echo "one ";
case 2:
echo "two ";
case "hello":
echo "hello ";
}
will output:
one two hello
PHP finds the first case condition to be true and starts executing statements without evaluating any other case conditions.
This may be very counter-intuitive, and also makes the code less readable. It is best practice to put a break at the end of each case to avoid any misunderstanding.
It seems the order here is important, if you used:
$cond = "Night";
switch($cond){
case "Morning":
case "Night":
$name = "Good";
case "Night" :
echo $name." Night";
break;
case "Morning" :
echo $name." Morning";
break;
}
you would get what you expect. However as you see it can't be easily predicted what would be exact result, so depending on your needs, I would do it in different way, for example I would use 2 switches for that:
$cond = "Night";
$name = '';
switch($cond){
case "Morning":
case "Night":
$name = "Good";
break;
}
switch ($cond) {
case "Morning" :
echo $name." Morning";
break;
case "Night" :
echo $name." Night";
break;
}
or even simpler:
$cond = "Night";
$name = '';
switch($cond){
case "Morning":
case "Night":
$name = "Good";
break;
}
switch ($cond) {
case "Morning" :
case "Night" :
echo $name." ".$cond;
break;
}
Now everything will be obvious and noone will have difficulty to understand what's going on here.
To keep things organized you could do something like this. You will not need the switch
$cond = "Night";
$name = array (
'Morning' => 'Good',
'Night' => 'Good'
);
echo $name[ $cond ]." ".$cond;
In this case you don't have to add another switch case for new situations, just add an entry to the $name array
If you don't break; your switch it will continue and step into next cases.
$cond = "Night";
switch($cond){
case "Morning":
case "Night":
$name = "Good";
break; // add this
case "Morning" :
echo $name." Morning";
break;
case "Night" :
echo $name." Night";
break;
}
this happens also with other languages such as java, is called fall through
Try this code.
$cond = "Night";
$name = "Good ";
switch($cond){
case "Morning":
echo $name . $cond;
break;
case "Night":
echo $name . $cond;
break;
}

PHP switch entering case 0: even if there is a valid case? [duplicate]

This question already has answers here:
How to handle a PHP switch with different types?
(5 answers)
Closed 9 years ago.
The following switch case statement was supposed to execute the value of case "january": but instead it is executing the value of case 0: ,can anybody tell me why it is doing this?
CODE:
<?php
$a = "january";
switch ($a)
{
case 0:
case 3:
echo "The value is either 0 or 3";
break;
echo "0/2";
break;
case "january":
echo "january";
break;
case "march":
echo "The value is ";
break;
case 2:
echo "The value is 2";
break;
default:
echo "Here is ur default message";
break;
}
?>
By the way it is doing the same for the case "march"....?
$a = 'january';
var_dump($a == 0);
var_dump($a === 0);
var_dump($a == '0');
var_dump($a === '0');
Output:
bool(true)
bool(false)
bool(false)
bool(false)
Read up on Type Juggling. Apparently switch uses loose comparison:
Note:
Note that switch/case does loose comparision.
PHP has some problems that can cause this kind of behaviour, in this case the problem comes from the fact that you are using different types on your Switch.
Try this code:
echo (0 == "january") ? "true\n" : "false\n"; // Echoes true
One way to work around this is to use only strings on your switch, like so:
switch ($a)
{
case "0":
case "3":
echo "The value is either 0 or 3";
break;
echo "0/2";
break;
case "january":
echo "january";
break;
case "march":
echo "The value is ";
break;
case "2":
echo "The value is 2";
break;
default:
echo "Here is ur default message";
break;
}
This will work fine, because 0 == "0" but "january" != "0"
Switch uses simple == to compare the values of the variable with the ones on each case.
You need to put quotes around the numbers. You can't mix numbers and strings when using a switch statement.

Semi-colon after a case valid in a PHP switch statement?

I'm debugging some code for a client and found the following syntax:
switch ($i) {
case 0;
echo "i equals 0";
break;
case 1;
echo "i equals 1";
break;
case 2;
echo "i equals 2";
break;
}
The case statements end in semi-colons rather than colons. Turns out this does compile, but is it legit? I've never seen that syntax before.
From the documentation:
It's possible to use a semicolon instead of a colon after a case like:
switch($beer)
{
case 'tuborg';
case 'carlsberg';
case 'heineken';
echo 'Good choice';
break;
default;
echo 'Please make a new selection...';
break;
}
As you can check here, it works: http://codepad.org/hOLQP98D i think it works because it falls through
Yup, just as long as $i has a number value

Is it possible to use || in PHP switch?

switch ($foo)
{
case 3 || 5:
bar();
break;
case 2:
apple();
break;
}
In the above code, is the first switch statement valid? I want it to call the function bar() if the value of $foo is either 3 or 5
You should take advantage of the fall through of switch statements:
switch ($foo)
{
case 3:
case 5:
bar();
break;
case 2:
apple();
break;
}
The PHP man page has some examples just like this.
I think what you need is:
switch ($foo)
{
case 3:
case 5:
bar();
break;
case 2:
apple();
break;
}
Interestingly, I've heard that Perl is (or maybe even has, by now) introducing this syntax, something along the lines of:
if ($a == 3 || 5)
I'm not a big fan of that syntax since I've had to write lexical parsers quite a bit and believe languages should be as unambiguous as possible. But then, Perl has solved all these sorts of problems before with those hideous tail-side ifs and ors so I suspect there'll be no trouble with it :-)
Instead, use one of the primary advantages of switch statements:
switch($foo) {
case 3:
case 5:
bar();
break;
case 2:
apple();
break;
}
Yeah, I think what you've got there is equivalent to:
<?php
$foo = 5000 ;
switch( $foo )
{
case true : // Gzipp: an '=='-style comparison is made
echo 'first one' ; // between $foo and the value in the case
break; // so for values of $foo that are "truthy"
// you get this one all the time.
case 2:
echo 'second one';
break;
default:
echo 'neither' ;
break;
}
?>
No, if you wrote case 3 || 5:, then you might as well just write case True:, which is certainly not what you wanted. You can however put case statements directly underneath each other:
switch ($foo)
{
case 3:
case 5:
bar();
break;
case 2:
apple();
break;
}

Categories