php类型比较背后的基本原理
php网站上有一个页面显示了比较不同值的结果: 这是一个有用的参考资料,但我不希望每次都要访问这个页面来确保我做的是正确的类型比较。所以我的问题是 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
- 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)
在阵列前端同样棘手
当使用严格的比较(==
和!==
)时,事情会变得更加理智。在实践中,根据需要转换来自超全局函数和数据库的输入,并从此点开始使用这些运算符通常是一个好主意。