PHP的变量类型宽大

时间:2011-11-24 14:36:57

标签: php

关于PHP的in_array()帮助页面(http://uk.php.net/manual/en/function.in-array.php#106319)的最新评论指出,由于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不关心它是否为空?)

任何人都可以提供任何指示吗?

3 个答案:

答案 0 :(得分:4)

763 == true,因为true等于任何不为0,NULL或''的东西,对于数组来说都是一样的,因为它是一个值(不是对象)。

为了避免这个问题,你应该将第三个参数作为TRUE传递给STRICT,因此,is_rray将执行===这是一个类型相等所以

763!== true

并且array()!== true

都不会

答案 1 :(得分:1)

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

?>

另外,'egg'不是数组中的值,它是键,所以当然令人惊讶的是它会返回true。这种行为在我所知道的任何其他语言中都不行,所以它会绊倒许多内心不知道php怪癖的人。

在PHP中违反了一个简单的规则:空字符串是假的:

if( "0" ) {
echo "hello"; //not executed
}

"0"是任何可以想象的定义的非空字符串,但它是一个假值。

答案 2 :(得分:1)

在内部,你可以认为基本的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值,那么基本上可以找到您使用in_array进行搜索的所有内容,并且几乎除PHP中的以下所有内容都可以将类型转换为true:

'' == TRUE // false
0 == TRUE // false
FALSE == TRUE // false
array() == TRUE // false
'0' == TRUE // false

但:

'a' == TRUE // true
1 == TRUE // true
'1' == TRUE // true
3.1415926 = TRUE // true
etc...

这就是为什么in_array有可选的第3个参数来强制进行严格比较。它只是让in_array进行===严格比较,而不是==

这意味着

'a' === TRUE // FALSE