switch variable gets first instance in php [duplicate] - php

This question already has answers here:
switch statement with multiple cases which execute the same code
(3 answers)
Closed 5 years ago.
I want to store a certain value during a switch/case in PHP, but I don't see what is wrong with this code:
<?php
$weegfactor=67;
$lus=12;
if($weegfactor<70):
switch($lus){
case(1 || 7):
$verdeling="AAABCD";
break;
case(2 || 8):
$verdeling="AAABBE";
break;
case(3 || 9):
$verdeling="AAAABC";
break;
case(4 || 10):
$verdeling="AABBBD";
break;
case(5 || 11):
$verdeling="ABBBCC";
break;
case(6 || 12):
$verdeling="AABCCC";
break;
}
endif;
echo "weegfactor ",$weegfactor . '</br>' ;
echo "lus : ",$lus . '</br>';
echo "verdeling ",$verdeling;
?>
The outcome of the above code is:
weegfactor 67
lus : 12
verdeling AAABCD
Which is not correct because $verdeling should be "AABCCC".
What is my mistake??

1 || 7 evaluates to a boolean type. So your program is doing a boolean comparison of $lus and (1 || 7).
You will need to use two separate case statements for each:
switch($lus){
case(1):
case(7):
$verdeling="AAABCD";
break;
case(2):
case(8):
$verdeling="AAABBE";
break;
case(3):
case(9):
$verdeling="AAAABC";
break;
case(4):
case(10):
$verdeling="AABBBD";
break;
case(5):
case(11):
$verdeling="ABBBCC";
break;
case(6):
case(12):
$verdeling="AABCCC";
break;
}

With case (x || y) you probably mean when it is x or y. In that case you should do this:
switch($lus) {
case x:
case y:
// do stuff
break;
}
What you have now is a check against x || y, which is always resolves to a "truish" value, just like your value 12 is "truish", making the switch take the first branch.

The value of 1 || 7 is TRUE, because both 1 and 7 are truthy. So the first case is equivalent to:
case TRUE:
And in fact, all your cases are equivalent to case TRUE:.
So it's then testing $lus == TRUE. When comparing any type to a boolean, the other type is first converted to boolean (see Comparison Operators for the complete list of how loose comparisons of different types are done). Since 12 is truthy (any non-zero integer is truthy), this comparison succeeds.
If you want to test against multiple values, use multiple case statements:
case 1:
case 7:
$verdeling="AAABCD";
break;

Related

ternary operator is not working as expected instead throws an error

<?php echo date("d")===1? "st": (date("d")===2? "nd" :(date("d")===3? "rd":"th")):"th"; ?>
Here's what i would want if day===1 then print out st otherwise if date===2 it should print nd otherwise if date===3 print out rd otherwise print out the default th
here is the error emitted
Parse error: syntax error, unexpected ':', expecting ',' or ';'
I totally forgot about date format S:
echo date("DS");
A parsing error occurs when the language syntax rules are broken. Your code does not compile, therefore it is not executed. The error is produced by the fragment :"th" that follows the last closed parenthesis. Remove it and the code will compile.
However, it will not work correctly because you use === to compare a string (returned by date()) against a number (1, 2 or 3). Such a comparison never succeeds because === compares both the types of the operands and their values.
Read about the PHP comparison operators == and ===.
There are also logical errors in your code. date('d') returns the current day of month. On the 21st, 22nd, 23rd and 31st of the month the code uses an incorrect suffix.
A better approach, with is also easier to read, is to use a switch statement like this:
$day = date('d');
switch ($day) {
case '01':
case '21':
case '31:
$suffix = 'st';
break;
case '02':
case '22':
$suffix = 'nd';
break;
case '03:
case '23':
$suffix = 'rd';
break;
default:
$suffix = 'th';
break;
}
echo("${day}${suffix}");
Or you can work smarter, not harder, and use the j and S format specifiers of date and let PHP do the heavy lifting:
echo(date('jS'));
Check it online.
date() and the other date & time functions are old and out of fashion since about 10 years ago. I recommend you to use the DateTime class and its friends. They are easier to use to do date & time computations and they can handle timezones (the old functions cannot).
Try this:
<?php echo date("d")===1 ?
"st" :
(
date("d")===2 ?
"nd" :
(
date("d")===3?
"rd":"th"
)
); // You had here :"th"; ?>
The :"th" at the end (see the comment in the code) breaks the ternary
operator syntax.

How to check multiple comparisons in PHP not using an if or case?

So I know you could do something simple like this to set a variable equal to one thing if the condition is true and one thing if it is false.
$height > 70 ? $output = "Taller than 6 foot" : $output = "Shorter than 6 foot";
But how would I go through and check multiple things like this not using an if statement? For example, if I wanted to check if height was between 5 and 6, between 4 and 5, between 3 and 4 and more, and then only echo out one $result based on which category $height fell in, how would I do that? Could I just add something useless after the : such as a variable I would never use?
The only way to parameterize this would be to use switch which is mostly the same as using ifs but with a multiple verifications. Sadly, there's no shorter way to write this. (There might be, but they might be cumbersome to write / read which is not always an advantage!).
Here's a switch / case statement that uses multiple conditions. Usually, you pass the variable to the switch statement and you use the case statements with variables or possible values, but since the possible values are conditions, you need to pass true as a parameter as this is the value to be expected. You can reverse this by passing false if needed.
switch(true){
case ($my_number > 3):
echo "Greater than 3";
break;
case ($my_number <= 3):
echo "Smaller or equal to 3";
break;
}
you can make nested conditions:
$output = ($height < 6 && $height > 5) ? 'something' : (($height <= 3) ? 'less t. 3' : 'over 4')
but this is not really readable, I would avoid this, syntax with multiple conditions is better with if/switch

Switch too often triggered

I cannot get my head around this. There might be a simple solution and the problem addressed already, but I could not find an answer.
<?php
$string = '';
$array = array(1, 2, 3);
foreach($array as $number) {
switch($number) {
case '1':
$string .= 'I ';
case '2':
$string .= 'love ';
case '3':
$string .= 'you';
}
}
echo $string;
?>
As you might have guessed, the sentence produced should be: I love you
But that is the actual output: I love youlove youyou
How is this even possible, when the switch is only triggered thrice.
Meanwhile I know that the problem can be fixed with a >break;< after each case. But I still do not understand why this is necessary.
I would be very happy, if someone could explain to me what PHP is doing.
Happy Valentines!
When case 1 is matched it will also execute case 2 and 3 unless there is a break.
So each time through the loop the matched case and everything following is executed.
First time: case 1, 2, 3
Second time: case 2, 3
Third time: case 3
For reference, here's an extract from the PHP documentation on switch, which explains it better than I probably would. :)
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. For example:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
Here, if $i is equal to 0, PHP would execute all of the echo statements! If $i is equal to 1, PHP would execute the last two echo statements. You would get the expected behavior ('i equals 2' would be displayed) only if $i is equal to 2. Thus, it is important not to forget break statements (even though you may want to avoid supplying them on purpose under certain circumstances).
When you don't specify a break the code execution will fall-through to the next case.
As an example an exam paper with a score out of 10 could be graded as such:
switch ($score)
{
case 10:
// A+ when score is 10
echo 'A+';
break;
case 9:
case 8:
// A when score is 8 or 9
echo 'A';
break;
case 7:
case 6:
// B when score is 7 or 6
echo 'B';
break;
case 5:
case 4:
case 3:
// C when score between 3 and 5
echo 'C';
break;
default:
// Failed if score is less than 3
echo 'Failed';
}

Conditional switch statements in PHP

I'm quite used to vb.net's Select Case syntax which is essentially a switch statement, where you can do things like Case Is > 5 and if it matches, it will execute that case.
How can I do what I'm going to call "conditional switch statements" since I don't know the actual name, in PHP?
Or, what's a quick way to manage this?
switch($test)
{
case < 0.1:
// do stuff
break;
}
That's what I've tried currently.
I think you're searching for something like this (this is not exactly what you want or at least what I understand is your need).
switch (true) finds the cases which evaluate to a truthy value, and execute the code within until the first break; it encounters.
<?php
switch (true) {
case ($totaltime <= 1):
echo "That was fast!";
break;
case ($totaltime <= 5):
echo "Not fast!";
break;
case ($totaltime <= 10):
echo "That's slooooow";
break;
}
?>
I tried to add this as a comment to the answer by BoltCock, but SO is telling me that his answer is locked so I'll make this a separate (and essentially redundant) answer:
The "switch(true)" answer from BoltCock is much like the following example, which although logically equivalent to if + else if + else is arguably more beautiful because the conditional expressions are vertically aligned, and is standard/accepted practice in PHP.
But the if + else if + else syntax is essentially universal across scripting languages and therefore immediately readable (and maintainable) by anyone, which gives it my nod as well.
There is an additional way you can accomplish this, in PHP 8.0+, by using a match statement.
If you have a single expression within each case, it is equivalent to the following match statement. Note that unlike switch statements, we can choose to return a variable (in this code I am storing the result in $result).
$test = 0.05;
$result = match (true) {
$test < 0.1 => "I'm less than 0.1",
$test < 0.01 => "I'm less than 0.01",
default => "default",
};
var_dump($result);
Match statements only allow you to have a single expression after each condition. You can work around this limitation by calling a function.
function tinyCase(){}
function veryTinyCase(){}
function defaultCase(){}
$test = 0.01;
match (true) {
$test < 0.1 => tinyCase(),
$test < 0.01 => veryTinyCase(),
default => defaultCase(),
};
And for reference, if you just want to check for equality you can do:
$result = match ($test) { // This example shows doing something other than match(true)
0.1 => "I'm equal to 0.1",
0.01 => "I'm equal to 0.01",
default => "default",
};
Match statements do have some key differences from switch statements that you need to watch out for:
My last example will use a strict equality check === instead of a loose one ==.
If a default case is not provided, an UnhandledMatchError error is thrown when nothing matches.
And there is no worrying about falling through to the next case if you forget to add break.
PHP supports switch statements. Is that what you wanted?
Switch statement with conditions
switch(true)
{
case ($car == "Audi" || $car == "Mercedes"):
echo "German cars are amazing";
break;
case ($car == "Jaguar"):
echo "Jaguar is the best";
break;
default:
echo "$car is Ok";
}

Can I use a logical "or" in a PHP switch statement case?

Is it possible to use "or" or "and" in a switch case? Here's what I'm after:
case 4 || 5:
echo "Hilo";
break;
No, but you can do this:
case 4:
case 5:
echo "Hilo";
break;
See the PHP manual.
EDIT: About the AND case: switch only checks one variable, so this won't work, in this case you can do this:
switch ($a) {
case 4:
if ($b == 5) {
echo "Hilo";
}
break;
// Other cases here
}
The way you achieve this effectively is :
CASE 4 :
CASE 5 :
echo "Hilo";
break;
It's called a switch statement with fall through. From Wikipedia :
"In C and similarly-constructed languages, the lack of break keywords to cause fall through of program execution from one block to the next is used extensively. For example, if n=2, the fourth case statement will produce a match to the control variable. The next line outputs "n is an even number.". Execution continues through the next 3 case statements and to the next line, which outputs "n is a prime number.". The break line after this causes the switch statement to conclude. If the user types in more than one digit, the default block is executed, producing an error message."
No, I believe that will evaluate as (4 || 5) which is always true, but you could say:
case 4:
case 5:
// do something
break;
you could just stack the cases:
switch($something) {
case 4:
case 5:
//do something
break;
}
switch($a) {
case 4 || 5:
echo 'working';
break;
}

Categories