php类型比较背后的基础哲学

时间:2013-04-16 22:28:57

标签: php types comparison boolean-operations

因此php网站上有这个页面显示比较不同值的结果:

http://php.net/manual/en/types.comparisons.php

这是一个有用的参考,但每次我想确保我正在进行类型比较时,我宁愿不必访问此页面。所以我的问题是

PHP上的类型比较逻辑背后是否存在某种基础哲学/推理?

例如,我可以看到松散的比较:

  • 1,-1,“1”和“-1”可以视为TRUE 0和“0”可视为FALSE;
  • 将数字的字符串值与数字本身进行比较,得率为TRUE;

但是在尝试建立模式时,它会变得有点毛茸茸。

7 个答案:

答案 0 :(得分:6)

直接转换为布尔值,这就是它的工作原理。

  • 所有字符串长度> 0是真的
  • 所有非0数字均为真
  • 所有非空数组都是真的
  • 所有对象都是真的

然后这些规则用于比较相同类型的变量:

  1. 如果对象属性相等,则对象是等效的
  2. 如果它们的键和元素相等,则数组是等效的
  3. 如果字符串产生相同的输出
  4. ,则它们是等效的
  5. 如果数字在数学上是等价的,则数字相等
  6. 如果布尔值具有相同的值,则它们是等效的。
  7. 对于不同类型的变量,上面列表中较高的类型将转换为低于进行比较的类型。

    ===!==运算符在比较之前不进行强制转换,但如果它们是同一个实例,则应注意对象仅为===

    真正奇怪的是数组,如果它们具有相同的键和值,则它们是===

    $a = array("a"=>1, "b"=>2);
    $b = array("b"=>2, "a"=>1);
    
    $a == $b; // true
    $a === $b; // false
    

    empty()相当于!(bool)$var

    <强>例外

    • 将数组转换为字符串会触发通知,并且无法有效地转换为文本Array
    • 将没有__toString方法的对象强制转换为字符串会导致致命错误。
    • 对象不会隐式地转换为数组,因此每次将对象与数组进行比较时都会产生错误(更新确认即使对象实现了{{1}也是如此} interface)

答案 1 :(得分:4)

对于严格的===比较,逻辑很简单:每个值实体仅与自身相等,因此TRUE === TRUE"1" === "1",但"1" !== 1等。

对于==比较,遗憾的是,没有经验法则或明确的逻辑。这可能是因为操作员的各种形式是由不同的程序员实现的,没有中央设计决策。我能做的最好的就是为你提供这个图表来打印和粘贴在显示器上:

PHP equality graph

grap的关键是:A == B TRUE当且仅当AB有两种直接连接时通过上图中的一行。例如,array() == NULLTRUE,因为array()NULL是直接相关的,而array() == 0FALSE,因为没有连接两者的行

以红色标记的行是棘手的(非显而易见的)等值

我已经省略了每个实体都等于它自己(例如"1" == "1"等)但这应该很容易记住。

作为最后一点,我想解释为什么"php" == 0TRUE(非空,非数字字符串等于0):因为PHP强制转换{{1}比较前编号,因为它不是数字,所以默认为"php"并进行测试0

有趣的事实:这种关系中没有分区!如果允许传递闭包,你可以很容易地说 True是假而False是真的,在四个简单的PHP语句中摧毁了数千年的哲学:D

答案 2 :(得分:2)

如果值包含某些内容,则可以说它是true。例如,11.123array("value")等都被视为true

如果该值可以说是空或无效(即缺少某些东西),那么它被视为false。例如,00.0array()等等。

这种思考变量的方式对PHP来说并不特殊。许多其他语言以相同或相似的方式进行。例如。 Perl,C和Javascript,仅举几例。

答案 3 :(得分:2)

规范中有一个非常简单的指南和错误,可能会令人困惑。

严格比较检查数据类型和值的相等性。 松散比较仅检查值的相等性。

对于一个对象(不是比较表的一部分),php非常简单: 如果对象与另一个对象是同一个实例,那么它是否严格相等,否则它可能是松散相等的。

因此是0和&#34; 0&#34;松散地彼此相等并且是假的(和任何字符串)。后者可以理解为所有字符串都不是数字,因此为false且等于false的数字为0,因此所有字符串都等于0.

null和array()之间的比较更复杂。如果检查使用array()创建的数组并进行松散且严格的比较,那么它将返回true。但是如果你用is_null检查它,那么它将返回false。我认为后者更合乎逻辑,因为用array()创建的array()不等于&#39;&#39;,其中null是。我认为函数is_null()和检查之间的这种功能不一致 == null或=== null一个错误,因为不应该发生使用两个不同的有效方法来检查值返回不同的结果。 根据函数is_array(),Null也不是数组,这是真的。空数组是根据函数is_array()的数组,也应该是真的。因此,如果null等于array(),那么它永远不会是真的。

答案 4 :(得分:1)

没有特别的逻辑,但你可以找出一些模式。

  • “空”值(nullfalse0,空字符串和字符串'0')评估为false
  • 数值的比较是隐式地将它们转换为整数直到某个版本(当两个实际上不同的长数字字符串计为相等时存在错误,现在它已修复)
  • 使用数组时,整数和数字索引之间没有区别,除非使用显式strict参数调用array_key_exists
  • 将数字与字符串进行比较会隐式地将右参数转换为左边的类型
  • return ($something);隐式将$something转换为字符串(如果它不是标量

答案 5 :(得分:1)

基本模式与C中使用的模式相同:为了布尔比较,任何非零都是正确的。

从这个意义上说,空字符串或数组也是假的。

要注意的毛茸茸的标量是'0',它(非常不方便地)也被视为空,因为它被转换为整数。 array(0)在阵列方面同样棘手。

使用严格的比较(===!==)时,事情会更加明智。实际上,在适当的时候输入来自超级全局和数据库的输入通常是一个好主意,并从那时起使用这些操作符。

答案 6 :(得分:0)

我用以下方式看待它:

  1. PHP被设计为一种网络编程语言,页面的所有输入都是基于字符串[类似人类的感知] [顺便说一句,这也适用于JavaScript]
  2. 因此,看起来像数字的所有字符串(is_numeric()函数),初步表现为数字[比较,演员]。
  3. 这就解释了为什么像“0”这样的极端情况首先被隐含地认为是强制转换为(int)0 而只有 false >