Edson Horacio Junior
Edson Horacio Junior

Reputation: 3143

PHP boolean casting awkward

I came to this issue at work and wondered why PHP behave like this:

$test = "insert";

$isInsert1 = $test == "update";             // false
$isInsert2 = (boolean) ($test == "update"); // false
$isInsert3 = (boolean) $test == "update";   // true

$isInsert3 should return false like the other two variables, shouldn't it? I think that for some reason, wich i don't know, php considers the $test variable before comparing it with "update" string.

I'd like someone to explain me that behavior.

Upvotes: 0

Views: 132

Answers (5)

dognose
dognose

Reputation: 20899

What PHP is "seeing" here:

first:

$isInsert1 = $test == "update";             // false

<=> $isInsert1 = ($test == "update"); 
<=> $isInerst1 = ("insert" == "update");
<=> $isInerst1 = (false) // -> false.

second:

$isInsert2 = (boolean) ($test == "update"); // false

<=> $isInerst2 = (boolean) ("insert" == "update");
<=> $isInerst2 = (boolean) (false);
<=> $isInsert2 = false; // false

third:

$isInsert3 = (boolean) $test == "update";   // true

<=> $isInsert3 = (((boolean) $test) == "update"); //$test "isset"
<=> $isInsert3 = (true == "update"); //"update" "isset"  ps.: true === "update" would be false!
<=> $isInsert3 = (true); // -> true

See: http://php.net/manual/en/language.operators.precedence.php

I think your main "Confusion" is the fact, that true == "update" equals true. This is, because == in PHP means equal, but === means IDENTICAL!

See here for more information: http://www.php.net/manual/en/language.operators.comparison.php

bool == ANYTHING will cause the right side to be casted to bool. And when casting to bool:

(boolean)1 == (boolean)2 == (boolean)"AnyNotEmptyString" == true

and

false == (boolean)0 == (boolean)null == (boolean)"". (and whatever I missed)

Note: NOT EVEN the String-represenation of a boolean will be casted to the boolean in question. When comparing a String with a boolean, all that matters is: Is the string empty (or null, or "0")? then its FALSE!:

(Boolean)"false" == false // -> will return false
(Boolean)"false" == true // -> will return true.
(Boolean)"true" == true // -> will return true.
(Boolean)"true" == false// -> will return false.
(Boolean)"0" == true // -> will return false.
(Boolean)"0" == false// -> will return true.

Snipped:

   <?php
echo ((Boolean)"false" == false)?"true":"false";
echo "<br />";
echo ((Boolean)"false" == true)?"true":"false";
echo "<br />";
echo ((Boolean)"true" == true)?"true":"false";
echo "<br />";
echo ((Boolean)"true" == false)?"true":"false";
echo "<br />";
echo ((Boolean)"0" == true)?"true":"false";
echo "<br />";
echo ((Boolean)"0" == false)?"true":"false";
?>

Upvotes: 2

Surreal Dreams
Surreal Dreams

Reputation: 26380

The cause of this unexpected behavior is that in your third instance, you are casting $test to boolean, not the outcome of $test == "update".

Casting "insert" to bool results in true - any non-empty string evaluates as true. Then true == "string" evaluates to true, because the comparison of a boolean to other types treats both types as boolean. Again, a non empty string like "string" is equivalent to true, so true == true, not surprisingly is equal to true.

Footnote - If you are comparing two variables with an operator like ==, you don't need to cast the result to boolean. The result will always be boolean.

Upvotes: 0

Oswaldo Acauan
Oswaldo Acauan

Reputation: 2740

Without the parentesis you are casting $test to boolean.

Strings always evaluate to boolean true unless they have a value that's considered "empty" by PHP (taken from the documentation for empty):

  1. "" (an empty string)
  2. "0" (0 as a string)

So in your case PHP are interpreting:

  1. $isInsert3 = (boolean) $test == "update";
  2. $isInsert3 = ((boolean) $test) == "update";
  3. $isInsert3 = true == "update";
  4. $isInsert3 = true == true;

Upvotes: 1

Tomasz Kapłoński
Tomasz Kapłoński

Reputation: 1378

The issue is connected with operator precedence. Actually (boolean) is operator with higher precedence than comparison. This means that the third line is equivalent of

$tmp = (boolean) $test; //true
$isInsert3 = (bool == "update"); // boolean true and non-empty string are treated as equal when you do ==

Upvotes: 1

Ming-Tang
Ming-Tang

Reputation: 17651

In the third line, (boolean) $test == "update" is interpreted as ((boolean) $test) == "update". Then, PHP tries to evaluate true == "update" because a non-empty string is true, and then, the right hand side, "update" casts into true, so true == true is true.

Upvotes: 5

Related Questions