problem with conditional switch
The example below is an extráct from http://p开发者_如何学Pythonhp.net/manual/de/control-structures.switch.php
<?php
$totaltime = 0;
switch ($totaltime) {
case ($totaltime < 1):
echo "That was fast!";
break;
case ($totaltime > 1):
echo "Not fast!";
break;
case ($totaltime > 10):
echo "That's slooooow";
break;
}
?>
I expected the result as "That was fast." But actual result is "Not fast!". It would be great if some one can explain me why?
But if i add another case, case 0: echo "That was super fast!".
Then it is echoing properly. i.e "That was super fast!". Please help me how to use conditional switch statement.
EDIT:-
Thanks all for your responses. I am able to overcome the above problem by modifyong switch($totaltime) to switch(1)
case ($totaltime < 1):
means 1
to PHP (that equation returns true)
case ($totaltime > 1):
means 0
to PHP (that equation returns false)
Since $totaltime
is 0, you get that output
In other words PHP compares $totaltime
to the result of the comparisons.
EDIT regarding EDIT in OP:
You need to get rid of the switch()
-statement. You only use it to easily compare against different values and not use additional expressions with it.
I mean what is wrong with
<?php
$totaltime = 0;
if ($totaltime < 1) {
echo "That was fast!";
} else if ($totaltime > 10) {
echo "That's slooooow";
} else if ($totaltime > 1) {
echo "Not fast!";
}
?>
EDIT: please note that I switched the last two if-statements to make it really work.
You don't use conditionals in the case
statements like that, not intuitively anyway. This is what's happening:
case ($totaltime < 1): // Evaluates to 1. $totaltime is not 1, so no match.
case ($totaltime > 1): // Evaluates to 0. $totaltime is 0, so match.
Essentially you're trying to use an else if
construct as a switch
construct, but the functionality isn't there. The conditionals don't evaluate in the way you're expecting (the way they would in an if
block), they're just looking for the first case
block which equals the value being tested in the switch
block.
Hate to necro a post that's already answered but I am rather baffled no one touched on the switch(true) method.
There is no real world speed advantage of either method
In some cases the switch was faster, others the if was faster, but only by fractions of a microsecond (48.16 µs vs 49.11 µs switch faster than if).
EDIT
And now I see the OP did the same...
<?php
for ( $totaltime = 0; $totaltime < 11; $totaltime += 0.5 ) {
switch ( true ) {
case ( $totaltime < 1 ):
echo $totaltime . " That was fast!\n";
break;
case ( $totaltime < 10 ):
echo $totaltime . " Not fast!\n";
break;
default:
echo $totaltime . " That's slooooow\n";
break;
}
}
Results: https://3v4l.org/d71lZ
0 That was fast!
0.5 That was fast!
1 Not fast!
1.5 Not fast!
2 Not fast!
2.5 Not fast!
3 Not fast!
3.5 Not fast!
4 Not fast!
4.5 Not fast!
5 Not fast!
5.5 Not fast!
6 Not fast!
6.5 Not fast!
7 Not fast!
7.5 Not fast!
8 Not fast!
8.5 Not fast!
9 Not fast!
9.5 Not fast!
10 That's slooooow
10.5 That's slooooow
It would almost seem that this is a bolean conversion issue.
The first case statement will evaluate to anything other than 0, so that will not hit.
But the second case statement will evaluate to false, which should be 0 which is equal to what you have set $totaltime to.
Lucky,
PHP switch is same as series of IF statements. The cases are evaluated as:
if($totaltime == ($totaltime < 1)) {
echo "That was fast!";
break;
}
if($totaltime == ($totaltime > 1)) {
echo "Not fast!";
break;
}
...
Clearly 0 == false for 2nd IF is true and hence the result.
Thanks, Vikas.
Others have mentioned why this is occurring (misuse of a conditional in the case statement), but they haven't offered alternatives. Switch is meant to cover specific arguments like { 0, 1, 2, 3..100, 101 } etc. It separates out specific arguments or ranges rather than performing a simple if/else (as you've used it). You can rewrite your arguments to pull it off though:
switch ($totaltime) {
case (0):
echo "That was fast!";
break;
case (1..PHP_INT_MAX):
echo "Not fast!";
break;
default:
echo "That's slooooow";
break;
}
Here the .. allows a range to be covered, so anything from 1 to integer max is covered by that case. The 0 is handled explicitly and all others (re: < 0) are covered by the default case.
精彩评论