PHP 8.0 中用 strpos() 判断子串存在需用 !== false 严格比较,避免 0 被误判为 false;推荐直接使用 str_contains(),语义清晰、UTF-8 安全、无需类型判断。

PHP 8.0 中用 strpos() 判断子串是否存在,却因返回 0 被当成 false 导致业务逻辑出错——这不是偶发问题,而是类型松散比较引发的典型陷阱。核心不在函数本身,而在判断写法是否严格。
为什么 0 == false 会翻车
当目标子串恰好出现在字符串开头时,strpos() 返回整数 0。而 PHP 的 ==(双等号)会自动类型转换:0 == false 结果为 true。于是本该进入“存在分支”的代码,被错误跳过。
-
$url = '/admin/dashboard'; if (strpos($url, '/admin') == false) { /* 这里会被执行! */ }—— 明明匹配成功,却进了“未找到”逻辑 - 常见于权限校验、路由前缀判断、敏感词拦截等场景,上线后才暴露,排查困难
修复方法:必须用严格比较
唯一可靠解法是使用 !== false(全等),明确区分整数 0 和布尔 false。
- ✅ 正确写法:
if (strpos($str, $needle) !== false) - ❌ 错误写法:
if (!strpos($str, $needle))或if (strpos($str, $needle) == false) - 若需忽略大小写,改用
stripos(),同样要配合!== false
更优替代:直接升级到 str_contains()
PHP 8.0+ 原生提供 str_contains(),语义清晰、无类型干扰,专为“是否存在”设计。
立即学习“PHP免费学习笔记(深入)”;
- ✅
if (str_contains($url, '/admin')) { /* 安全进入 */ } - 自动处理空字符串:
str_contains('abc', '')恒为true,定义稳定 - 无需记忆返回值含义,代码可读性高,新人也不易踩坑
中文或 UTF-8 场景要额外注意
如果待查内容含中文、emoji 等多字节字符,strpos() 仍可能因字节偏移失准而返回 false(即使子串真实存在)。
- ✅ 应改用
mb_strpos($str, $needle, 0, 'UTF-8'),并同样用!== false判断 - ⚠️
str_contains()在 PHP 8.0+ 中已原生支持 UTF-8,无需额外指定编码,更省心



















