为什么对 strstr 的调用没有返回 false?

Why is this call to strstr not returning false?

我在旧的遗留代码库中偶然发现了 strstr 的问题。代码很多,但基本上测试用例会归结为:

$value = 2660;
$link = 'affiliateid=1449&zoneid=6011&placement_id=11736&publisher_id=1449&period_preset=yesterday&period_start=2017-03-27&period_end=2017-03-27';

var_dump(strstr($link, $value));

我希望这是 return false 因为“2660”不在字符串中但是它 returns d=1449&zoneid=6011&placement_id=11736&publisher_id=1449&period_preset=yesterday&period_start=2017-03-27&period_end=2017-03-27.

我知道 $value 应该是一个字符串,但我仍然不明白为什么 PHP 没有将它转换为字符串以及为什么它在 link 中找到这个数字.

实际上,如果我尝试使用 $value = '2660'; 它 returns false 正如预期的那样。

知道发生了什么吗?

我认为这回答了你的问题:

needle
If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.

http://php.net/manual/en/function.strstr.php

根据评论进行编辑:

chr(2660) return 的角色 d,确实是大海捞针,这就是为什么它不会像你预期的那样 return false。

简答

当你 运行 strstr($str, 2660)$needle 被解析为字符 "d" 通过调用 chr(2660),因此它在给定 $str 中找到的第一个 "d" 处停止,在此第 11 个字符的大小写。


我们为什么打电话给 chr(2660)

因为当 $needle 不是字符串时 strstr casts that argument to an integer and uses the corresponding character for that position from the extended ASCII code 其中 chr(2660)"d".

If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.


但是为什么 chr(2660) return "d""d"ord(100)?

因为超出有效范围[0-255]的值会按位与255相加,相当于下面的算法[source]

while ($ascii < 0) {
    $ascii += 256;
}
$ascii %= 256;

所以,2660变成100,然后传递给strstr时,它作为字符的序数值,查找字符"d"

令人困惑? 。我还希望它被转换为一个字符串,但这就是我们在编程中假设的结果。至少,这是有记录的;您会惊讶于 奇怪 发生的次数如此之多,而且找不到官方解释。至少不像遵循您提供的 link 那样容易。


为什么命名为strstr

我做了一些研究,发现 this gem(理由 美国国家标准 对于信息系统 - 编程语言 - C) 从 1989 年开始,他们用前缀 str 命名所有与字符串相关的函数,这是合乎逻辑的,然后由于 PHP 的源代码是用 C 编写的,它将解释为什么它带有.我最好的猜测是我们正在另一个 string 中搜索 string,他们确实说:

The strstr function is an invention of the Committee. It is included as a hook for efficient substring algorithms, or for built-in substring instructions.

有用的文档