PHP布尔铸造尴尬

时间:2013-10-21 19:23:10

标签: php casting boolean

我在工作中遇到了这个问题,并想知道为什么PHP的行为如下:

$test = "insert";

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

$ isInsert3应该像其他两个变量一样返回false,不应该吗?我认为由于某种原因,我不知道,php在将它与“update”字符串进行比较之前考虑了$ test变量。

我希望有人向我解释这种行为。

5 个答案:

答案 0 :(得分:5)

在第三行中,(boolean) $test == "update"被解释为((boolean) $test) == "update"。 然后,PHP尝试评估true == "update",因为非空字符串为true,然后右侧"update"转换为true,因此true == true为真。

答案 1 :(得分:2)

PHP在这里“看到”:

第一

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

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

第二

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

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

第三

$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

请参阅:http://php.net/manual/en/language.operators.precedence.php

我认为你的主要“困惑”是true == "update"等于true。 这是因为PHP中的==表示相等,但===表示IDENTICAL!

有关详细信息,请参阅此处:http://www.php.net/manual/en/language.operators.comparison.php

bool == ANYTHING会导致右侧变为bool。当铸造到布尔时:

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

false == (boolean)0 == (boolean)null == (boolean)""。 (以及我错过的任何东西)

注意:即使布尔值的字符串表示将被转换为有问题的布尔值。将String与布尔值进行比较时,重要的是:字符串是否为空(或为空或“0”)?那就错了!

(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.

剪断:

   <?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";
?>

答案 2 :(得分:1)

如果没有使用parentesis,您将$test强制转换为布尔值。

字符串总是计算为布尔值true,除非它们的值被PHP视为“空”(取自documentation for empty):

  1. ""(空字符串)
  2. "0"(0为字符串)
  3. 因此,在您的情况下,PHP正在解释:

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

答案 3 :(得分:1)

该问题与operator precedence有关。实际上(布尔值)是具有比比较更高优先级的运算符。这意味着第三行等同于

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

答案 4 :(得分:0)

这种意外行为的原因在于,在第三个实例中,您将$test投射到布尔值, $test == "update"的结果。

将“insert”转换为bool会导致true - 任何非空字符串的计算结果为true。然后true == "string"求值为true,因为布尔值与其他类型的比较将两种类型都视为布尔值。同样,像“string”这样的非空字符串相当于true,因此true == true,毫不奇怪,等于true。

脚注 - 如果要将两个变量与==之类的运算符进行比较,则无需将结果转换为boolean。结果将始终为布尔值。