strpos判断是否包含需用!==false,因0被当作false;中文须用mb_strpos并指定UTF-8编码;大小写不敏感应使用stripos或mb_stripos;offset参数在strpos与mb_strpos中含义不同。

strpos 不能直接用来“判断是否包含”,它只返回位置;用错比较方式(比如 if (strpos(...)))会把开头匹配到的情况当成“没找到”。
为什么 strpos 返回 0 时 if 判断会失效
因为 strpos 在子串位于字符串开头时返回整数 0,而 PHP 中 0 == false 成立,但 0 !== false 才是真判断。松散比较会让逻辑翻车。
- 错误写法:
if (strpos($str, 'a')) { ... }—— 当$str = 'abc'时,strpos返回0,整个条件为false,代码块被跳过 - 正确写法:
if (strpos($str, 'a') !== false) { ... } - 注意:必须用
!==或===,!=同样不可靠
中文或 UTF-8 字符串必须换 mb_strpos
strpos 按字节定位,UTF-8 中文占 3 字节,strpos 可能切在中间导致乱码、偏移错位或直接返回 false。即使字符串看起来“找到了”,位置值也可能是错的。
- 先确认
mbstring扩展已启用:php -m | grep mbstring,没输出就需在php.ini中取消注释extension=mbstring - 调用时必须显式指定编码:
mb_strpos($str, '你好', 0, 'UTF-8');省略第 4 个参数可能 fallback 到系统默认编码,结果不可控 -
mb_strpos返回的是字符位置(从 0 开始),不是字节偏移,和strpos的语义一致但更安全
大小写不敏感?别硬改逻辑,直接用 stripos
自己 strtolower() 再查不仅多一次复制开销,还可能破坏原始字符串结构(比如含二进制数据或混合编码)。PHP 已提供原生方案。
立即学习“PHP免费学习笔记(深入)”;
-
stripos($str, 'hello')行为与strpos完全一致,只是忽略大小写 - 同样必须用
!== false判断,规则不变 - 不支持正则,也不处理多字节 —— 如果要对中文做不区分大小写的搜索,得组合
mb_stripos(PHP 7.3+)并确保编码明确
最容易被忽略的点:函数第三个参数 $offset 是字节偏移(strpos)还是字符偏移(mb_strpos),取决于你用哪个函数;混用会导致位置计算完全错位,而且这种 bug 往往只在特定长度或特定字符组合下才暴露。



















