当前位置: 首页 > 知识库问答 >
问题:

为什么in\u array()返回意外/奇怪的结果?

琴献
2023-03-14

为什么in\u array()有时表现得如此奇怪,并返回如此意外的结果?

我们来看几个例子:

$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];

var_dump(in_array('Gary', $arrayWithTrue)); // returns bool(true)
var_dump(in_array(0, $arrayWithNull)); // returns bool(true)
var_dump(in_array(true, $arrayWithMinusOne)); // returns bool(true)

嗯?这里发生了什么!?

(几年前,我开始怀疑这种奇怪的行为。不过我认为它可能对某些人有用,所以我进入了这个问题。)

共有1个答案

明财
2023-03-14

始终在第三个参数strict中使用\u array():

$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];

var_dump(in_array('Gary', $arrayWithTrue, true)); // returns bool(false)
var_dump(in_array(0, $arrayWithNull, true)); // returns bool(false)
var_dump(in_array(true, [-1], true)); // returns bool(false)

因此,当您将in\u array()true一起用作第三个参数时,搜索值与数组之间的比较是严格进行的,这意味着in\u array()的工作与您可能预期的一样。

(php.net文档中也描述了参数strict。)

如果未将参数strict设置为true,则搜索值与数组的每个值之间的比较是通过相等而不是通过标识来完成的。这意味着值的类型无关紧要,因此PHP在内部将值转换为相同的数据类型,以便能够比较它们。

这意味着在第一个示例中,搜索到的值'Gary'在与true进行比较时被转换为布尔值,因此它会导致truetrue进行比较,这显然是true

第二个数组也是如此,其中最后将0null进行比较,结果为true,尽管0显然与null不同(例如,在处理数字和/或函数结果时,这可能特别棘手,其中null可以表示空值,而不是0)。

第三个数组看起来很奇怪,因为我们检查数组中的值true,它只包含-1,但是in\u array()仍然返回true进行比较。在这种情况下,将-1转换为布尔值true。所以问题在两个方向上都是一样的。

您可以在这个堆栈溢出答案中找到有关PHP中比较问题的更多示例(因为这与PHP中的比较问题相同)。

不幸的是,调用in_array()时严格参数的默认值是...好吧,是的,false。:-/PHP,它正在输入...

如果没有将严格的参数设置为true,则绝对不能调用\u array()中的。如果没有混合类型的数组,并且只检查同一类型的值,则in\u array()会按预期工作。请参见此示例:

$arrayWithStrings = ['Andreas', 'Philipp', 'Friedrich'];
var_dump(in_array('Gary', $arrayWithStrings)); // returns bool(false)

所以,至少这是预期的效果。但在我看来,总是用stricttrue调用\u array()要容易得多。(类似于“SQL注入问题”…只要始终使用PDO和prepared语句,这样就安全了,即使它是一个没有可变参数的查询。那么您就永远安全了。)

您肯定应该使用stricttrue在\u array()中调用。但我确实想提及一个缺点(尽管这是显而易见的)。在\u array()中调用时,必须使用正确的类型,然后:

$arrayWithNumbers = [1, 2, 3];
var_dump(in_array('1', $arrayWithNumbers, true)); // returns bool(false)

但是你可以只使用类型铸造,当你知道你比较数字:

$arrayWithNumbers = [1, 2, 3];
var_dump(in_array((int)'1', $arrayWithNumbers, true)); // returns bool(true)
// Comparing false with an empty array
var_dump(in_array(false, [[]])); // returns bool(true)

嗯,是的。。。只需将strict设置为true即可使用它;-)

 类似资料:
  • 我的程序读取一个自定义生成的字符串,它遵循以下模式: #INT{0,1,2}/STRING/LONG#INT{0,1,2}/STRING/LONG## 这是字符串开头和结尾的一个散列,分隔每个子字符串,每个子字符串包含0-2的int、字符串名称和长值(取自系统时钟)。这些子值由前斜杠分隔。 我的程序成功地在函数“splitOnHash”的散列上拆分了主字符串,并将其分配给一个字符串数组列表,我可以

  • 我使用了以下映射:我修改了英语分析器来使用ngram分析器,如下所示,这样我应该能够在以下情况下进行搜索:1]部分搜索和特殊字符搜索2]以获得语言分析器的优势 将我的数据索引如下:

  • 问题内容: 我正在尝试使用Java的SimpleDateFormat来解析带有以下代码的日期字符串。 我期待一些解析错误。但有趣的是,它打印以下字符串。 无法推理出来。有人可以帮忙吗? 谢谢 问题答案: 已将其解析为 月份 号2011,因为month()是日期模式的第一部分。 如果将2011个月加到28年,则得到195年。 2011个月是167年零7个月。七月是第七个月。您将02指定为日,将28指

  • 问题内容: 我正在使用Python 3.6.1,但遇到了一些非常奇怪的事情。我有一个简单的字典作业错字,花了很长时间才找到。 输出量 代码在做什么?IMO应该什么时候都没有提出。起初,我认为它正在创建一个切片。但是,键入会引发一个。我也输入了控制台,但控制台没有打印任何内容。我以为也许它回来了,但是我不太确定。 我还认为这可能是单行if语句,但这也不应该是正确的语法。 此外,应提出一个。 我很困惑

  • 但是,当从handleAsyncErrors()流链接ObjectNode并到达相同的httpCallbackFlow()时,我们会得到一个异常,该异常由 restClientException:无法写入请求:在org.springframework.web.client.restTemplate$HttpEntityRequestCallback.dowithRequest(restTempla

  • 所以看起来第一个被稍微回滚,可能是时区对应的两个小时?但为什么这种情况只发生在一个案子上呢?用2000年做同样的实验不会产生同样的错误。