为什么这个调用strstr不返回false?

时间:2017-03-28 10:10:23

标签: php string casting strstr

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

我希望这会返回false,因为“2660”不在字符串中,但会返回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转换为字符串,为什么它会在链接中找到这个数字。

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

知道发生了什么事吗?

2 个答案:

答案 0 :(得分:38)

简短回答

当您运行strstr($str, 2660)时,$needle通过调用{{1}解析为" d " 因此它会在给定的chr(2660)中找到的第一个" d " 停止,在这种情况下就是在第11个字符处

<小时/>

为什么我们打电话给$str

因为当chr(2660)不是字符串时strstr将该参数强制转换为整数,并使用extended ASCII code$needle所在的[source]的相应字符。 >&#34;的 d &#34; 。

  

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

&#34; d chr(2660)会返回&#34; d &#34; >&#34; chr(2660)

因为有效范围ord(100)之外的值将按位并且与[0-255]一致,这相当于以下算法 strstr

255

因此,while ($ascii < 0) { $ascii += 256; } $ascii %= 256; 变为2660,然后传递给this gem时,它被用作角色的序数值并查找字符&#34 ;的 d &#34;

混淆? 即可。我也期望它被转换成一个字符串,但这就是我们在编程中假设的东西。这至少记录在案;你会发现怪异发生的次数并且没有官方解释,你会感到惊讶。至少不像跟随你提供的链接一样容易。

<小时/>

为什么命名为100

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

  

strstr功能是委员会的一项发明。它包括在内   作为高效子字符串算法的钩子,或用于内置的   子串指令。

有用的文档

答案 1 :(得分:8)

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

  

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

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

因为评论而编辑:

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