Reputation: 885
I am having a problem in php switch case.
When i set $number=0 it should run very first case but here this code returns 10-20K that is in second case.
I checked comparison operators, tested them in if else case they return correct values but here first case do not run on $number=0
Why is this happening ? php consider 0 as false or something wrong in code ?
Link to codepad paste http://codepad.org/2glDh39K
also here is the code
<?php
$number = 0;
switch ($number) {
case ($number <= 10000):
echo "0-10K";
break;
case ($number > 10000 && $number <= 20000):
echo "10-20K";
break;
case ($number > 20000 && $number <= 30000):
echo "20-30K";
break;
case ($number > 30000 && $number <= 40000):
echo "30-40K";
break;
case ($number > 40000 && $number <= 50000):
echo "40-50K";
break;
case ($number > 50000 && $number <= 60000):
echo "50-60K";
break;
case ($number > 60000 && $number <= 70000):
echo "60-70K";
break;
case ($number > 70000 && $number <= 80000):
echo "70-80K";
break;
case ($number > 80000 && $number <= 90000):
echo "80-90K";
break;
case ($number > 90000):
echo "90K+";
break;
default: //default
echo "N/A";
break;
}
?>
Upvotes: 4
Views: 3353
Reputation: 160863
switch ($number) {
case ($number <= 10000): // check $number == ($number <= 10000)
echo "0-10K";
break;
// you hit the below because `0 == false` is true in php
case ($number > 10000 && $number <= 20000): // check $number == ($number > 10000 && $number <= 20000)
echo "10-20K";
break;
// ...
But you could do it with less code:
function showRange($number) {
if ($number > 90000) {
echo "90K+";
return;
}
echo sprintf("%s-%sK", (int) ($number / 10000) * 10, ((int) ($number / 10000) +1) * 10 );
}
Upvotes: 4
Reputation: 437424
You are almost using the switch
in reverse, but not quite. You need to either go fully into reverse by writing switch(true)
:
switch (true) { // IMPORTANT CHANGE HERE!
case ($number <= 10000):
echo "0-10K";
break;
case ($number > 10000 && $number <= 20000):
echo "10-20K";
break;
// etc
}
or otherwise change the whole thing to if
/else
:
if ($number <= 10000) {
echo "0-10K";
else if ($number > 10000 && $number <= 20000) {
echo "10-20K";
}
// etc
Two important notes:
switch
usually looks terribly counter-intuitive the first time you see it. Please do not use it if you don't feel comfortable with it.$number > X
part is made redundant by the fact that the check in the previous conditional ($number <= X
) has already failed. However, it can be argued that keeping the checks makes the code more robust in the face of modification.Upvotes: 7
Reputation: 3042
$number = 0;
var_dump($number); // int(0)
If you modify the statement to be case ($number > 0 && $number <= 10000):
, it strangely works. But it works with any arbitrary lookup ($number > 9091 && $number <= 10000
) entered.
Even with the complete bollock below:
$number = 0;
$jonskeet = false;
switch ($number)
{
case ($jonskeet === true && $number <= 10000):
echo "0-10K";
// ...
It will output 0-10K
even though the same condition in an if
statement won't work.
The problem is that select
is not to be used with long conditionals. select
can be used to do something if the value of a variable is equal to what is after the case
keyword. See:
select ($user_rank)
{
case 0:
return "guest";
break;
case 1:
return "user";
break;
// ...
default:
return "unknown";
break;
}
But you have long conditions in the case
s of your code.
case ($number <= 10000):
echo "0-10K";
break;
case ($number > 10000 && $number <= 20000):
echo "10-20K";
break;
Running this first translates $number <= 10000
to TRUE and $number > 10000 && $number <= 20000
to FALSE, like two statements. And after this, your code is executed in the manner below:
case TRUE:
echo "0-10K";
break;
case FALSE:
echo "10-20K";
break;
$number
is 0
, but it can evaulate to FALSE
too, this is why you get the not desired output.
As a solution, you should translate your code to have an if
-elseif
-else
setup:
if ( $number < 10000 ) {
echo "0-10K";
} else if ( $number > 10000 && $number <= 20000 ) {
echo "10-20K";
// ...
} else {
echo "N/A";
}
Upvotes: 3
Reputation: 634
Here, if $i is equal to 0, PHP would execute all of the echo statements!
so its execute the statement of next case and in that case there is break so out from it
so use the if-else-if instead of switch case
if ($number <= 10000){
echo "0-10K";
}elseif( $number <= 20000){
echo "10-20K";
}elseif( $number <= 30000){
echo "20-30K";
}elseif( $number <= 40000){
echo "90K+";
}
...
elseif( $number <= 90000)
echo "80-90K";
}elseif($number > 90000){
echo "90K+";
}
Upvotes: 1
Reputation: 2156
You can't really do switch case for a range of number.Use if(){} else{} for this purpose.
Upvotes: 0
Reputation: 11869
Yes, for PHP 0
is FALSE
(unless you use ===
). And yes, your code is incorrect - switch
isn't for comparing ranges - it's for comparing values (at least in PHP, in Ruby or Perl 6 it's another matter), like there.
switch ($letter) {
case 'a':
echo "A?";
break;
default:
echo "Unknown letter";
break;
}
In your case, you compare number to conditions - those either return true
or false
. As 0
is false
, the second condition catches. switch
wasn't made for code like that, I would use if
else
instead or rewrite your logic - repeating isn't good idea.
$range_number = floor($number / 1000);
echo $range_number, $range_number ? "K" : "", "-", $range_number + 1, "K";
(by the way, I know that switch (true)
works, but don't use it - it's ugly hack)
Upvotes: 1
Reputation: 47976
When you execute a switch case method, you can't match against a boolean value like that. You need only compare the resulting value.
I think you should rewrite your code to use if...then...elseif
statements.
if ($number <= 10000){
echo "0-10K";
}elseif($number <= 20000){
echo "10-20K";
}elseif($number <= 30000){
echo "20-30K";
}elseif($number <= 40000){
...
}
By using this method you don't need to make two checks each time because the previous if
statements check those conditions as well. IE: If you reach the second if
statement, you already know that the value is not smaller than (or equal to) 1000
therefore it must be larger than 10000
.
Upvotes: 3