PHP strpos 查找整数类型的值异常分析及解决方法

最近运营的同事反映,用户发布的帖子内容很多都进入到了待审核状态

由于我们系统中有一套敏感词检查的机制,如果包含敏感词则帖子进入先审后发

其中就用到了strpos 函数,众所周知,strpos用于查找字符串中某个子串第一次出现的位置。

每次数据来了,想要查找这个字符串中某个字符是否存在,就会使用到它。

但是我们排查发现在某些帖子实际中并没有存在设置的关键词,那这个又是因为什么呢?

排查发现是运营设置了部分纯数字的关键词

分析

假设有一个字符串"I don't happy ! xxxx585xxx",现在需要找到585出现的位置,检查其是否存在该关键词。

理想状态中我们可能认为代码这样抒写即可,当然可能大部分时候也确实是这样写的

$string ='I don\'t happy ! xxxx585xxx';
$numtmp = 585;
echo strpos($string,$numtmp);   

但是我们在检查结果中却出人意料的出现了错误,其输出结果是0,但我们的期望值是20

这时候就出现了一个结果的误差,虽然检查585的时候是0,会判断字符串中存在这个内容,但如果是检查5则会是false。

原因

那本着寻求本真的精神,原因到底是什么呢?在参考了部分资料之后得出结论

strpos对于非字符串类型的数据使用php_needle_char做了一次类型转换,强制类型转换。

C 代码,如果是整数类型,则强制转换成char类型。所以当你传入585的时候,使用char进行强转之后得到的结果是字符串"I",所以实际上截取之后的字符串长度为0。

现在就很清晰明了了,因为PHP底层对数值型的参数做了一次强制的转化,使得她本身检查的内容发生了变化,才出现结果的误差

 需要注意类型转换分为下列几种情况:

 1、整形,长整型直接转成char类型

 2、布尔值,分别转成字符'1','0',所以strpost('e1',true);返回内容为1

 3、double类型数据,先强转为长整型再转换成char类型

 4、对象则对对象id进行char的转换

 5、其他类型触发E_WARNING的警告到这里就了解了为什么给一个整数,strpos会有意向不到的结果。

 解决方案

既然系统需要字符型数据,那我们则对被检查的数据 提前进行 (string) 处理皆可

//方案1
$string ='I don\'t happy ! xxxx585xxx';
$numtmp = '585';
echo strpos($string, $numtmp);

//方案2
$string ='I don\'t happy ! xxxx585xxx';
$numtmp = 585;
echo strpos($string, (string)$numtmp);

这样我们就得到了预期的结果~

作者:旧旧的 <[email protected]> 解决问题的方式,就是解决它一次

猜你喜欢

转载自www.cnblogs.com/widgetbox/p/12095541.html
今日推荐