应使用 strpos($str, $needle) !== false 判断子串存在,因 strpos() 在子串位于开头时返回 0,而 0 == true 为 false 导致误判;PHP 8.0+ 推荐 str_contains()。

用 strpos() 判断子串存在,但别直接用 == true
PHP 里最常用也最容易出错的方式就是 strpos()。它返回子串首次出现的位置(从 0 开始),没找到才返回 false。问题就出在:如果子串恰好在开头(位置 0),0 == true 是 false,结果就误判为“不存在”。
- 必须用严格比较:
strpos($str, $needle) !== false,不能是!= false或== true - 注意参数顺序:
strpos($haystack, $needle),反了会报Warning: strpos(): Empty needle - 区分大小写:默认敏感,要忽略大小写请用
stripos() - 性能上,
strpos()是 C 实现的,比preg_match()快得多,简单包含检测优先选它
需要全字匹配或复杂模式?别硬套 strpos()
比如判断字符串是否“等于某个词”,或“以某词结尾”,或“包含但不跨单词边界”,strpos() 就力不从心了。
- 检查是否以某子串开头:用
str_starts_with($str, $prefix)(PHP 8.0+),低版本可用substr($str, 0, strlen($prefix)) === $prefix - 检查是否以某子串结尾:用
str_ends_with($str, $suffix)(PHP 8.0+),否则用substr($str, -strlen($suffix)) === $suffix - 要确保是独立单词(如 “cat” 不匹配 “category”):得用正则,
preg_match('/\bcat\b/', $str),注意转义和分隔符 - 正则虽灵活,但开销明显大于
strpos(),纯固定子串就别用
str_contains() 是 PHP 8.0 后最干净的写法
如果你项目已用 PHP 8.0+,直接上 str_contains(),语义清晰、无类型陷阱、性能和 strpos() 持平。
- 写法极简:
str_contains($str, $needle),返回true或false - 不支持部分匹配控制(比如只查前 N 个字符),也不支持偏移量;有这类需求还得回退到
strpos() - 注意:它不处理编码——如果字符串含多字节字符(如中文、emoji),且用了非 UTF-8 编码,结果可能异常;此时应先确认
mb_internal_encoding()设置正确
常见错误现象和兼容性兜底方案
线上突然报错或逻辑翻车,往往不是逻辑错,而是环境差异导致的函数不可用或行为偏移。
立即学习“PHP免费学习笔记(深入)”;
- 本地 PHP 8.1 跑得好,服务器还是 7.4?
str_contains()和str_starts_with()直接Fatal error: Uncaught Error: Call to undefined function - 用
mb_strpos()替代strpos()处理中文时,忘了传第四个参数$encoding,默认按 ISO-8859-1 解码,中文全变 - 判断空字符串:
str_contains('', 'a')返回false,符合直觉;但strpos('', 'a')返回false,容易和“没找到”混淆——这点其实两者一致,关键是别自己脑补逻辑 - 兜底写法(兼容 5.6+):
if (!function_exists('str_contains')) { function str_contains(string $haystack, string $needle): bool { return '' === $needle || false !== strpos($haystack, $needle); } }
phpversion() 和字符串编码。











