【问题标题】:How does true/false work in PHP?真/假在 PHP 中是如何工作的?
【发布时间】:2011-01-23 20:38:27
【问题描述】:

我想知道 PHP 如何在内部处理 true/false 比较。 我知道 true 定义为 1, false 定义为 0。 当我执行if("a"){ echo "true";} 时,它会回显“true”。 PHP如何将“a”识别为 1 ?

【问题讨论】:

  • “真定义为1,假定义为0”过于简单化了。
  • 顺便说一句。猜猜这会返回什么:"false" == true

标签: php


【解决方案1】:

这在 booleanstype comparison tables 的 PHP 文档中有介绍。

当转换为布尔值时,以下值被认为是 FALSE:

  • 布尔值FALSE 本身
  • 整数0(零)
  • 浮点数0.0(零)
  • 空字符串和字符串'0'
  • 零元素的数组
  • 一个成员变量为零的对象(仅限 PHP 4)
  • 特殊类型NULL(包括未设置的变量)
  • 从空标签创建的 SimpleXML 对象

所有其他值都被视为 TRUE

【讨论】:

  • "程序员社区" != sh != bash 等等。而且我用过的任何编程或脚本语言都没有约定任何非零都是错误的(当然这不是意味着没有,但它是一个相当不错的样本集)。虽然我绝对更喜欢强类型并且对 PHP 完全不能忍受,但“truthy”和“falsey”值在允许比较原本无法比较的类型以及如何确定给定类型的真实性的语言中非常常见在给定的语言中可能非常随意。
  • 请注意,当@MarkByers 说“字符串“0””时,这是完全正确的。例如,字符串“00”、字符串“0.0”、“\0”等不会同样为假。
  • 您应该在您的答案中添加,以检查 var 是否真的是布尔值,严格比较必须与 === 运算符一起使用,而不是常用的 ==
【解决方案2】:

因为我已经多次访问此页面,所以我决定发布一个示例(松散)比较测试。

结果:

""         -> false
"0"        -> false
"0.0"      -> true
"1"        -> true
"01"       -> true
"abc"      -> true
"true"     -> true
"false"    -> true
"null"     -> true
0          -> false
0.1        -> true
1          -> true
1.1        -> true
-42        -> true
"NAN"      -> true
0          -> false
NAN        -> true
null       -> false
true       -> true
false      -> false
[]         -> false
[""]       -> true
["0"]      -> true
[0]        -> true
[null]     -> true
["a"]      -> true
{}         -> true
{}         -> true
{"t":"s"}  -> true
{"c":null} -> true

测试代码:

class Vegetable {}

class Fruit {
    public $t = "s";
}

class Water {
    public $c = null;
}

$cases = [
    "",
    "0",
    "0.0",
    "1",
    "01",
    "abc",
    "true",
    "false",
    "null",
    0,
    0.1,
    1,
    1.1,
    -42,
    "NAN",
    (float) "NAN",
    NAN,
    null,
    true,
    false,
    [],
    [""],
    ["0"],
    [0],
    [null],
    ["a"],
    new stdClass(),
    new Vegetable(),
    new Fruit(),
    new Water(),
];

echo "<pre>" . PHP_EOL;

foreach ($cases as $case) {
    printf("%s -> %s" . PHP_EOL, str_pad(json_encode($case), 10, " ", STR_PAD_RIGHT), json_encode( $case == true ));
}

总结:

  • 完成严格 (===) 比较后,除 true 之外的所有内容均返回 false
  • 空字符串 ("") 是假的
  • 仅包含 0 ("0") 的字符串是假的
  • NAN 是真的
  • 一个空数组 ([]) 是假的
  • 包含假值的容器(数组、对象、字符串)为真
    • 一个例外是0 in ""(见第三项)

【讨论】:

    【解决方案3】:

    零为假,非零为真。

    在 php 中,您可以使用 === 运算符进行更明确的测试。

    if (0==false) 
        echo "works"; // will echo works
    
    if (0===false) 
        echo "works"; // will not echo anything
    

    【讨论】:

    • 为什么0 === false 不起作用? 0 === false0 === FALSE 之间也有区别吗?
    • 0 === false0 === FALSE 没有区别。两个 false 评估为相同的值;对于函数名称和语言关键字,PHP 令人讨厌地不区分大小写。这两个“工作”,但他们评估为假,因为=== 实际上做了一个依赖于类型的值检查。 == 允许类型之间的检查;请参阅此线程上接受的答案,了解 PHP 如何确定哪些匹配 false 哪些不匹配。
    【解决方案4】:

    严格检查的最佳算子是

    if($foo === true){}
    

    这样,您实际上是在检查它是否为真,而不是 1 或只是设置。

    【讨论】:

      【解决方案5】:

      PHP 使用弱类型(它称之为“类型杂耍”),这是一个坏主意(尽管这是另一个话题)。当您尝试在需要布尔值的上下文中使用变量时,它将根据此处提供的一些大多数任意规则将您的变量转换为布尔值: http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting

      【讨论】:

      • 那个“坏主意”纯粹是主观的:一旦你知道它是如何工作的,在我看来这绝对不是问题;-);;并且转换规则对我来说似乎不太合乎逻辑;-)
      • 不要让我发布一个关于弱类型的想法有多糟糕的stackoverflow问题;)。考虑到 php 设法使基本三段论失败,因为隐式类型转换使 php 相等性不可传递: echo ("true" == true)."\n"; //真回声(真== 1)。“\n”; // true echo ("true" == 1)."\n"; // 假 :P
      • 是的……这对新玩家来说是一个(可能)非常危险的把戏,但不一定是个坏主意。我不会在这里为代码的健壮性辩护,但有时它是一个不错的捷径。此外,如果您正在做大量更大规模的工作,您可能会在大部分时间使用相等方法。
      【解决方案6】:

      将运算符视为一元函数:is_false(type value),它返回 true 或 false,具体取决于特定类型和值的确切实现。考虑 if 语句通过语法糖隐式调用此类函数。

      另一种可能性是该类型具有强制转换运算符,它将类型隐式转换为另一种类型,在本例中为字符串到布尔值。

      PHP 没有公开这些细节,但 C++ 允许运算符重载,从而公开了运算符实现的细节。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-02
        • 2011-01-13
        • 2013-04-04
        • 2013-01-06
        相关资源
        最近更新 更多