php类型比较背后的基本原理

php类型比较背后的基本原理,php,types,comparison,boolean-operations,Php,Types,Comparison,Boolean Operations,php网站上有一个页面显示了比较不同值的结果: 这是一个有用的参考资料,但我不希望每次都要访问这个页面来确保我做的是正确的类型比较。所以我的问题是 PHP上的类型比较逻辑背后是否有某种潜在的哲学/推理? 例如,对于松散的比较,我可以看到: 1、-1、“1”和“-1”可以视为真,0和“0”可以视为假 将数字的字符串值与数字本身进行比较,得到TRUE 但从那时起,试图建立一个模式就变得有点毛茸茸的。如果该值包含某些内容,则可以说它是真的。例如,1、1.123、数组(“值”)等都被视为true

php网站上有一个页面显示了比较不同值的结果:

这是一个有用的参考资料,但我不希望每次都要访问这个页面来确保我做的是正确的类型比较。所以我的问题是

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

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

  • 1、-1、“1”和“-1”可以视为真,0和“0”可以视为假
  • 将数字的字符串值与数字本身进行比较,得到TRUE
但从那时起,试图建立一个模式就变得有点毛茸茸的。

如果该值包含某些内容,则可以说它是
真的。例如,
1
1.123
数组(“值”)
等都被视为
true

如果可以说该值为空或无效(即缺少某些内容),则该值被视为
false
。例如,
0
0.0
array()
,等等


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

对于直接转换为布尔值,这就是它的工作方式

  • 所有长度大于0的字符串都为真
  • 所有非0数字均为真
  • 所有非空数组都为true
  • 所有对象都是真实的
然后,比较相同类型变量的以下规则:

  • 如果对象的属性相等,则对象是等效的
  • 如果数组的键和元素相等,则它们是等价的
  • 如果字符串产生相同的输出,则它们是等价的
  • 如果数字在数学上是等价的,那么它们是等价的
  • 如果布尔值相同,则它们是等价的
  • 对于不同类型的变量,将上面列表中较高的类型转换为较低的类型,然后进行比较

    ==
    ==操作符在比较之前不强制转换,但是您应该注意,如果对象是相同的实例,那么它们只是
    ==

    真正奇怪的是数组,如果它们有相同的键和值以相同的顺序定义,那么它们就是
    =

    $a = array("a"=>1, "b"=>2);
    $b = array("b"=>2, "a"=>1);
    
    $a == $b; // true
    $a === $b; // false
    
    empty()
    相当于
    !(bool)$var

    例外情况

    • 将数组强制转换为字符串将触发通知,并无效地强制转换为文本
      array
    • 将没有
      \uuuu toString
      方法的对象强制转换为字符串将导致致命错误
    • 对象不会隐式强制转换为数组,因此,无论何时将对象与数组进行比较,都会产生一个false(更新确认这是真的,即使对象实现了
      ArrayAccess
      接口)

      • 没有特定的逻辑,但您可以找出一些模式

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

        imo有一个非常简单的指南,规范中有一个bug,可能会让人困惑

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

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

        因此,0和“0”大致相等,并且等于false(和任何字符串)。后者可以理解为所有字符串都不是数字,因此为false,等于false的数字为0,因此所有字符串都等于0

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

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

        从这个意义上讲,空字符串或数组也是false

        要注意的毛茸茸的标量是
        '0'
        ,它(非常不方便)也被视为空的,因为它被转换为整数<代码>阵列(0)
    在阵列前端同样棘手

    当使用严格的比较(
    ==
    !==
    )时,事情会变得更加理智。在实践中,根据需要转换来自超全局函数和数据库的输入,并从此点开始使用这些运算符通常是一个好主意。