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

2022-08-31 00:12:05

我偶然发现了一个旧遗留代码库中的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));

我希望这能返回,因为“2660”不在字符串中,但它返回。falsed=1449&zoneid=6011&placement_id=11736&publisher_id=1449&period_preset=yesterday&period_start=2017-03-27&period_end=2017-03-27

我意识到这应该是一个字符串,但我仍然不明白为什么它没有被PHP转换为字符串,以及为什么它在链接中找到这个数字。$value

实际上,如果我尝试使用它,它会按预期返回。$value = '2660';false

知道发生了什么吗?


答案 1

简短的回答

当您运行时,通过调用解析为字符d,因此它停止在给定的第一个d,在这种情况下,就在第11个字符处。strstr($str, 2660)$needlechr(2660)$str


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

因为当 不是字符串时,strstr 会将该参数转换为整数,并使用扩展 ASCII 代码中该位置的相应字符,其中 “d”。$needlechr(2660)

如果针不是字符串,则将其转换为整数并作为字符的序号值应用。


但是,为什么当“d是“d”时返回d呢?chr(2660)ord(100)

因为有效范围之外的值将是按位的,并且与 ,这等效于以下算法[source][0-255]255

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

因此,成为 ,然后当传递给 strstr 时,它被用作字符的序数值并查找字符d”。2660100

混乱?是的。我也希望它被转换为字符串,但这就是我们在编程中假设事物所得到的。这至少是有据可查的。你会惊讶于奇怪的事情发生的次数,并且没有找到官方的解释。至少不像点击您提供的相同链接那么容易。


为什么叫这个名字?strstr

我做了一些研究,发现了这个宝石(美国国家信息系统标准 - 编程语言 - C)的原理,可以追溯到1989年,他们用逻辑前缀命名了所有与字符串相关的函数,然后由于PHP的源代码是用C编写的,它将解释为什么它带有。我最好的猜测是,我们正在另一个string中寻找一个string,他们确实说:str

strstr函数是委员会的发明。它作为钩子包含在有效的子字符串算法或内置子字符串指令中。

有用的文档



答案 2

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


如果针不是字符串,则将其转换为整数并应用为字符的序号值。

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

由于注释而编辑:

chr(2660)返回字符 ,这确实在大海捞针中,这就是为什么它不会像你预期的那样返回假。d


推荐