PHP';s型可变宽大
最近对PHP的PHP';s型可变宽大,php,Php,最近对PHP的in_array()帮助页()的评论指出,由于PHP的“对变量类型的宽容”,出现了一些不寻常的结果,但没有解释为什么会出现这些结果。特别是,我不明白为什么会发生这些情况: // Example array $array = array( 'egg' => true, 'cheese' => false, 'hair' => 765, 'goblins' => null, 'ogres' => 'no ogres
in_array()
帮助页()的评论指出,由于PHP的“对变量类型的宽容”,出现了一些不寻常的结果,但没有解释为什么会出现这些结果。特别是,我不明白为什么会发生这些情况:
// Example array
$array = array(
'egg' => true,
'cheese' => false,
'hair' => 765,
'goblins' => null,
'ogres' => 'no ogres allowed in this array'
);
// Loose checking (this is the default, i.e. 3rd argument is false), return values are in comments
in_array(763, $array); // true
in_array('hhh', $array); // true
或者为什么海报认为以下行为很奇怪
in_array('egg', $array); // true
in_array(array(), $array); // true
(当然“egg”确实出现在数组中,PHP不关心它是键还是值,并且有一个数组,PHP不关心它是否为空?)
有人能给出任何指针吗?763==true,因为true等于任何非0、NULL或“”,数组也是这样,因为它是一个值(不是对象) 为了避免这个问题,您应该将第三个参数作为TRUE传递给STRICT,因此,is_rray将执行a===这是一个类型相等,因此 763!==真的
而且array()也不会真的PHP将数组视为原始值是一个经常令人痛苦的问题,因为它们可能是非常复杂的数据结构,这没有任何意义。例如,如果将数组指定给某个对象,然后修改该数组,则不会修改原始数组,而是复制该数组
<?php
$arr = array(
"key" => NULL
);
var_dump( array() == NULL ); //True :(
var_dump( in_array( array(), $arr ) ); //True, wtf? It's because apparently array() == NULL
var_dump( in_array( new stdClass, $arr ) ); //False, thank god
?>
“0”
根据任何可能的定义都是一个非空字符串,但它是一个伪值。在内部,您可以想象基本的in_array()调用是这样工作的:
function in_array($needle, $haystack, $strict = FALSE) {
foreach ($haystack as $key => $value) {
if ($strict === FALSE) {
if ($value == $needle) {
return($key);
}
} else {
if ($value === $needle) {
return($key);
}
}
return(FALSE);
}
请注意,它使用的是==
比较运算符-此运算符允许进行类型转换。因此,如果您的数组包含一个简单的布尔值TRUE
值,那么实际上,您在数组中搜索的所有内容都将被找到,并且除了PHP中的以下内容之外,几乎所有内容都可以被类型转换为TRUE:
'' == TRUE // false
0 == TRUE // false
FALSE == TRUE // false
array() == TRUE // false
'0' == TRUE // false
但是:
这就是为什么in_数组具有可选的第3个参数来强制进行严格比较。它只需在数组中执行==
严格比较,而不是=
也就是说
'a' === TRUE // FALSE
数组()!=是的;)你的意思可能是array()==false。我从内存中取出了它,但我早就完成了认证。谢谢你澄清这一点。在任何情况下,它都是有效的,因为数组中有一个true和一个false,所以每个In_数组调用都应该返回true,除了我不确定的对象的“maybe”之外。
In_数组
最重要的目的不是与任意类型的值进行比较,而是与字符串列表或所有整数进行比较。即使如此,它也只是使用Zends标准的弱类型规则此外,我们不应该在这里讨论php.net手动注释。只需提交一份bug报告。“PHP不在乎它是键还是值”——为什么你认为in_array
可以在数组键上工作?文档摘要清楚地说“检查数组中是否存在值”(emphasis mine)。javascript和perl中的“0”==false
。@MathieuDumoulin,在javascript中:if(“0”){alert(“hello”);}
按预期传递:“0”是真实值,因为它是非空字符串。在PHPif(“0”){echo“hello”;}
中,即使它是非空字符串,也不做任何事情。@gnud,这并不重要,因为在javascript中不这样做。如果使用if(“0”)
或if(x==true)
,则无需编写if==true
,因为正如您所看到的,它会产生意外的结果。区别在于,在javascript中,“0”是一个真实的值,而在php中,“0”是一个虚假的值。与true
相比,两者都被转换为0
,这在两种语言中给出了相同的结果。因此,javascript对if(“0”)
和if(“0”==true)
的处理方式不同,而你抱怨PHPs类型怪异?@gnud,if(某物)
在ecmascript规范中有很好的定义,没有什么意外NaN、-0、+0、空字符串、false、null、未定义的
将不通过,而其他所有内容都将通过。在PHP中,您可以在我对MathieDumoulin的回复中看到,情况并非如此。
'a' == TRUE // true
1 == TRUE // true
'1' == TRUE // true
3.1415926 = TRUE // true
etc...
'a' === TRUE // FALSE