strstr用于提取子串匹配后的剩余部分,而非判断存在性;需用str_contains()或strpos()!==false判断存在,用mb_strstr()处理中文,返回值须严格判false。

strstr 用来提取子串匹配后的剩余部分
它不是用来判断“是否存在”的,而是定位后切出一段内容。比如从邮箱 name@example.com 中取域名部分,strstr($email, '@') 返回 @example.com,而不是 true 或位置数字。
常见错误是把它当布尔判断用:if (strstr($str, 'abc')) { ... } —— 这逻辑上成立,但效率低、语义不清,且当 'abc' 出现在开头时(返回完整字符串),容易和 false 混淆(尤其没严格比较)。
- 只关心“有没有”,改用
str_contains()(PHP 8.0+)或strpos() !== false - 要取匹配点之后的内容,才用
strstr() - 要取匹配点之前的内容,加第三个参数
true:strstr($str, '.', true)
区分大小写 + 中文/ASCII 数字陷阱
strstr() 默认严格区分大小写,strstr('Apple', 'a') 返回 false,不是 'pple'。需要不区分时,换 stristr()。
PHP 8.0 起已彻底移除对数字 search 参数的支持。下面这行在 PHP 8.0+ 会报 TypeError:
strstr("hello", 101) // 101 是 'e' 的 ASCII,旧版能运行,新版不行
必须显式转成字符:
- 正确写法:
strstr("hello", chr(101))或strstr("hello", 'e') - 中文等多字节字符不能直接传入,否则可能截断乱码;需用
mb_strstr()并指定编码,如mb_strstr($str, '你好', false, 'UTF-8')
返回值必须严格判断是否为 false
strstr() 找不到时返回布尔值 false,找到时返回字符串(哪怕结果是空字符串 '')。所以不能用 if (strstr(...)) 简单判断——如果匹配内容恰好在末尾(如 strstr('abc', 'c') 返回 'c'),没问题;但如果匹配的是空串(PHP 8.0+ 支持),或你误把 false 当成空字符串处理,就会出错。
- 安全写法:
$result = strstr($haystack, $needle); if ($result !== false) { ... } - 不要用
==或隐式转换,'' == false为true,但'' !== false才是你要的区分 - 注意:PHP 8.0 允许
''作为$needle,此时总是返回原字符串(因为“空串在任意位置都存在”)
性能与替代函数选型
如果你只是检查子串存在性,strstr() 是最慢的选择之一——它要分配新字符串内存并复制数据。实际压测中,str_contains() 比 strstr() 快 2–3 倍,内存占用也更低。
- PHP 8.0+:优先用
str_contains($haystack, $needle) - PHP strpos($haystack, $needle) !== false
- 需要大小写不敏感:对应换成
str_contains($haystack, strtolower($needle))或stripos() - 只有当你明确需要“从匹配处开始的子串”时,才值得付出
strstr()的开销
真正容易被忽略的点是:很多人把 strstr() 当作“字符串查找通用函数”来记,但它其实是个“子串切片工具”。它的设计意图很窄——找位置 + 截后半段。一旦需求偏移(比如要位置索引、要多次匹配、要正则逻辑),立刻该换函数,硬套只会让代码变慢、难读、难维护。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











