range()和in_array()行为,我在这里做错了什么?

时间:2011-03-11 07:15:37

标签: php arrays

这是代码,检查输出 - > http://codepad.org/7n7dM54e

<?php

$key = "a";
$array = range("0","7");
echo "array is : \n";
var_dump($array);
echo "key is : $key \n";
echo "in_array result \n";
var_dump(in_array($key,$array)); // why is it true, 'a' is not a "0" string or 0 int
echo "array_search result \n";
var_dump(array_search($key,$array)); // why is it index 0

?>

2 个答案:

答案 0 :(得分:8)

解决方案

in_array()array_search()支持类型安全检查,第三个参数设置为true。不会执行任何转化,并会按原样比较值,并考虑类型(与===运算符一样)。

因此,如果您在每次函数调用结束时传递true,您将获得预期的结果:

// Both should return false
var_dump(in_array($key, $array, true));
var_dump(array_search($key, $array, true));

为什么会这样?

是的,它绝对是一种类型转换,但不是由in_array()array_search()专门实现的转换。它只不过是==运算符执行的松散比较。

两种方法都调用一个名为php_search_array()的C函数。此功能在/ext/standard/array.c中定义。以下是前几行中的一些内容:

static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ */
{
    // ---------- snip ----------

    int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;

    // ...

    if (strict) {
        is_equal_func = is_identical_function;
    }

    // ---------- snip ----------
}

如果我没错,那么你看到的is_equal_function只对应于==运算符,但不管数据类型如何,它都会进行非常简单的比较。可能会发生类型转换。 (同样,is_identical_function对应===。)

例如,'2abc' == 2为真,但'2abc' == 3为false。这是因为比较字符串和整数会导致在比较之前将字符串强制转换为整数。因此,将字符串'2abc'强制转换为int将返回2.

所以,就像我在下面所说的那样,当你将'a'传递给两个函数时,同样适用:它被转换为一个整数,产生0,它存在于{{返回的数组中1}}。就像我说的那样,range()返回一个整数数组(或浮点数),无论你是将整数还是数字字符串作为参数传递。

来自manual entry on PHP's comparison operators

  

如果您将数字与字符串进行比较,或者比较涉及数字字符串,则每个字符串都为converted to a number,并且数字执行比较。


旧“为什么会发生这种情况”

我认为range()in_array()的内部实现默认尝试将针转换为与被搜索数组中元素相同的类型。如果是这种情况,由于array_search()返回一个整数数组,字符串range()将转换为整数,即'a',因此将返回两个函数调用的结果。请注意,即使将数字作为字符串传递,0也会生成一个整数或浮点数组。

答案 1 :(得分:0)

嗯,这似乎是一个包含'0'的数组的错误

如果您将$array = range("0","7");更改为$array = range("1","7");,您就会明白我想说的是什么

http://codepad.org/3099zpch

另请阅读php手册http://php.net/manual/en/function.in-array.php

中的评论