为什么对 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.
有用的文档
我在旧的遗留代码库中偶然发现了 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.