strpos() 返回0时被if误判为false,因php松散比较将0视为假值;正确写法是用!== false严格比较;utf-8字符串需用mb_strpos并指定编码。

因为 strpos() 找到子串在开头时返回 0,而 PHP 松散比较(== 或直接用于 if)会把 0 == false 判为 true,导致“找到了”却被当成“没找到”。这不是 PHP7.4 特有,而是所有支持 strpos 的版本都存在的底层行为。
为什么用 if(strpos(...)) 总是错
strpos() 的设计逻辑是:返回位置索引(从 0 开始),没找到才返回布尔值 false。所以它合法返回值包括 0, 1, 2, ... 和 false。但 PHP 的 if 判断只认“真值/假值”,而 0 是假值——于是开头命中就被跳过。
-
strpos('abc', 'a')→ 返回0,if(0)不执行 -
strpos('abc', 'd')→ 返回false,if(false)也不执行 - 两者表现一样,但语义完全相反
正确写法只有一种:必须用 !== false
严格比较能区分类型和值:0 === false 是 false,false === false 才是 true。所以判断“是否找到”,逻辑上要写成“不等于 false”。
- ✅ 正确:
if (strpos($str, $needle) !== false) - ❌ 错误:
if (strpos($str, $needle))、if (strpos($str, $needle) != false)、if (strpos($str, $needle) == true)
中文或 UTF-8 字符串会雪上加霜
strpos 是按字节查找的。UTF-8 中一个中文占 3 字节,用它查 '你好' 很可能返回 false——不是不存在,是字节序列对不上。这时候光改判断条件没用,得换函数。
- 改用
mb_strpos($str, '你好', 0, 'UTF-8') - 第四个参数
'UTF-8'不能省,否则默认 ISO-8859-1,照样出错 - 它的返回值同样要判
!== false,规则一模一样
其他类似函数也踩同一坑
只要返回“位置整数 or false”的字符串函数,都得守这个规矩:
-
stripos()(忽略大小写)、strrpos()(找末次)、mb_stripos() - 比如用
strrpos($file, '.')提取扩展名,文件名是'.gitignore'时返回0,用== false就会误判为无点,后续substr()可能截出空或错位结果
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











