我在旧的遗留代码库中偶然发现了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
。
知道发生了什么事吗?
答案 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不是字符串,则将其转换为整数并应用为字符的序数值。
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功能是委员会的一项发明。它包括在内 作为高效子字符串算法的钩子,或用于内置的 子串指令。
chr
答案 1 :(得分:8)
我认为这回答了你的问题:
针 如果needle不是字符串,则将其转换为整数 应用为角色的序数值。
http://php.net/manual/en/function.strstr.php
因为评论而编辑:
chr(2660)
返回字符d
,这确实在大海捞针中,这就是为什么它不会像您预期的那样返回false。