Reputation: 347
I have the following PHP (the server is running version 5.3.x) in a script which is giving me a result that I am having trouble understanding. The general idea of this code is that I have a "normal mode", and two maintenance modes. In the first maintenance mode, data is only evaluated and can be viewed by an admin but is not stored to the database. If I set $maintenance_mode_enabled = 2;
, then the same "preview" output should be displayed but only SOME specific updates to the database should be processed. The reason I added the ==2
comparison is because I found the need for a third option after I had setup the true/false for the basic default maintenance mode. At any rate, I noticed 18 records on my last maintenance_mode_enabled = true;
run that were partially updated during the process, just as though I had set maintenance_mode_enabled = 2;
.
$maintenance_mode_enabled = true;
if ($maintenance_mode_enabled){
echo "Case 0\n";
}
if (!$maintenance_mode_enabled){
echo "Case 1\n";
}
if ($maintenance_mode_enabled == 2){
echo "Case 2\n";
}
The output I get is:
Case 0
Case 2
From what I understood, true (being boolean) is definitely not equal to 3. I am familiar with some oddities when comparing false, NULL and 0, but this problem with integers and TRUE is entirely new to me.
Any ideas as to why this isn't working? I realize that I can just as easily change $maintenance_mode_enabled
to an integer instead of a bolean by default, and set it as either 0, 1 or 2 to get the desired results, but I really want to understand WHY this seems to defy logic.
Upvotes: 1
Views: 2594
Reputation: 97
The reason this happens is because you're comparing a boolean to an integer. As with many languages, at the core of the comparison function it's casting the second part of your comparison to a boolean. Any non-NULL, non-zero, non-empty or non-false value, in this case 2
is "true."
As the previous answer mentions I would change the code to use strict comparison. I would also change from three separate if-statements to one if-elseif statement:
if ($maintenance_mode_enabled === true) {
// catches only true not > 0
echo "Case 0\n";
} elseif ($maintenance_mode_enabled === false) {
// catches only true not = 0
echo "Case 1\n";
} elseif ((int)$maintenance_mode_enabled === 2) {
echo "Case 2\n";
}
I recommend this change because maintenance mode can only have one value.
EDIT
I didn't realize true
and 2
could coexist. You could do:
if ($maintenance_mode_enabled) {
echo "Case 0\n";
if (2 === (int)$maintenance_mode_enabled) {
echo "Case 2\n";
}
} else {
echo "Case 1\n";
}
Upvotes: 4
Reputation: 5670
Use the ===
operator for true
otherwise all non 0 / null / false will be true
.
Use the ===
operator for false
otherwise all equal to 0 / false / null will show as "false"
The following will output Case 0
<?php
$maintenance_mode_enabled = true;
if ($maintenance_mode_enabled === true){
// catches only true not just > 0
echo "Case 0\n";
}
elseif (!$maintenance_mode_enabled === false){
// catches only false not including = 0
echo "Case 1\n";
}
elseif ($maintenance_mode_enabled == 2){
echo "Case 2\n";
}
?>
Upvotes: 1
Reputation: 347
Oh, NOW I get it. It seems the problem here is that when I do the loose (==
) comparison of a boolean with an integer, the type casting is converting the integer into a boolean, thus resulting in 2 being equal to true - since both are being tested as booleans. The solution is to use strict (===
) comparison, so that both must be of the same type... i.e.: 2 (integer), is not exactly the same as true, since true is is of a different type - boolean.
Upvotes: 0