Reputation: 12307
I am way confused with a comparison "error". The way I coded this comparison, I want to make sure that if the user inputs any value other than 0 or 1 (Or no value), the result should be 0:
session_start();
function test( $status = 0 ) {
if( !isset($_SESSION['status']) ) { $_SESSION['status'] = 0; }
else {
switch( $status ) {
case 0: $_SESSION['status'] = $status;
break;
case 1: $_SESSION['status'] = $status;
break;
default:
$_SESSION['status'] = 0;
$status = 0;
}
}
echo 'Variable value: ' . $status;
echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');
HOWEVER, it breaks at test('ready');
BECAUSE it outputs Variable value: ready | Session value: ready
RATHER THAN Variable value: 0 | Session value: 0
. It should continue to work well (and go for case o:
) even if it is comparing numbers against a string.
BTW: The result is the same even if I replace switch
for if( $status ===
=== EDIT: 12/19/2012 ===
Thanks to @bryan-b and @jatochnietdan comments and answers: -Because a string (when compaired with numbers [
if( 0 == 'string')] ) is compared as 0
That helped me figure out the problem and learned that, unlike in other languages, rather than automatically returning false in a comparison, since they are of different data-types; php compares string variables as if their value is 0 when compared against numbers.THAT'S SOMETHING TO WATCH OUT FOR.
This is the corrected (working) code:
session_start();
function test( $status = 0 ) {
if( !isset($_SESSION['status']) ) { $_SESSION['status'] = 0; }
else {
switch( $status ) {
case 1: $_SESSION['status'] = $status;
break;
default:
$_SESSION['status'] = 0;
$status = 0;
}
}
echo 'Variable value: ' . $status;
echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');
Thank you @bryan-b and @jatochnietdan!!!
PS. I wish I could vote 2 answers.
Upvotes: 1
Views: 656
Reputation: 8706
PHP is loosely typed, and string input can be evaluated as integers for comparisons (in fact, I think you're relying a bit on this for your code anyway).
Strings containing non-numeric characters will evaluate as integer 0 - so your cases in your switch statement will match 0 to 'ready' as easily as 0 to '0', and 1 to '1'.
So - you could just do:
$_SESSION['status'] = 0;
if ($status == 1) {
$_SESSION['status'] = 1;
}
Or make use of ctype functions to detect numeric values in strings.
Upvotes: 0
Reputation: 1063
If all you truly want is for the value of $_SESSION['status'] to be 0 if anything other than 1 is entered, then this should suffice:
function test( $status = 0 ) {
$_SESSION['status'] = ($status == 1 ? 1 : 0);
}
With your tests, the values will be as follows:
Session value: 0
Session value: 0
Session value: 1
Session value: 0
Session value: 0
Edit: Fixed a slight mistake, it was defaulting to 1 but I believe you want it to default to 0.
As for your code, the reason it's coming up as "ready" is because you're setting $_SESSION['status'] to $status in case 0 and $status contains "ready" in that instance. You could fix that by simply doing $_SESSION['status'] = 0.
Upvotes: 5
Reputation: 10686
This happens because switch in php uses something called: loose comparison.
That means that the string "value"
evaluates to 0
and thus it never reaches default as you might think.
Upvotes: 1
Reputation: 897
I think the problem here is that php is casting the string "ready" to an integer, so the case comparison works. From the php docs (http://php.net/manual/en/function.intval.php):
Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.
I've added an echo into the (working) function showing what php is doing when casting the string to an int for the switch comparisons. You need to be checking the exact value and type of the passed in status.
function test($status = 0){
if(!isset($_SESSION['status']) || $status !== 1){
$_SESSION['status'] = 0;
}
else {
$_SESSION['status'] = 1;
}
echo 'Variable value: ' . $status;
echo ' | Variable value (int): ' . (int)$status;
echo ' | Session value: ' . $_SESSION['status'] . "<br/>";
}
test();
test(0);
test(1);
test(999);
test('ready');
Upvotes: 3