strpos判断子串存在需用!== false,因0被误判为false;stripos忽略大小写;mb_strpos处理UTF-8中文/emoji;strstr返回匹配后子串,非位置;注意trim、编码、转义等干扰因素。

用 strpos 判断子串是否存在,别直接用 if (strpos(...))
PHP里最常踩的坑就是把 strpos 当布尔值直接判断。它在子串出现在开头(位置 0)时返回 0,而 if(0) 是 false,结果“明明找到了却说没找到”。
正确做法永远是显式比较返回值是否为 false:
if (strpos($str, 'abc') !== false) {
// 找到了
}
-
strpos区分大小写,要忽略大小写用stripos - 只返回首次匹配的位置(int),不关心后面还有没有
- 如果找不到,返回
false,不是-1或null—— 这点和 JavaScript 的indexOf不同 - 性能上比
strstr略快,因为它不拷贝字符串,只定位
用 strstr 提取匹配后的子串,注意返回值类型
strstr 不是返回位置,而是返回从第一次匹配开始到字符串末尾的**新字符串**。如果没找到,返回 false,不是原字符串。
常见误用:以为它返回布尔值,或者想当然地用 substr 去截取 —— 其实没必要,strstr 本身就能干这事。
立即学习“PHP免费学习笔记(深入)”;
- 默认返回包含匹配内容的后半段,比如
strstr('hello world', 'world')返回'world' - 加第三个参数
true可返回匹配前的部分:strstr('hello world', 'world', true)→'hello ' - 对空字符串或
null输入会触发 warning,使用前建议先is_string($str)校验 - 如果只要判断存在性,别用
strstr,它多做一次字符串复制,纯浪费
区分 strpos 和 mb_strpos:中文、emoji 场景必须用后者
PHP 默认的 strpos 是按字节查找的。遇到 UTF-8 编码的中文、emoji 或带重音符号的字母,一个字符占多个字节,strpos 就会错位甚至崩溃。
比如 strpos('你好世界', '世界') 看似该返回 6,但实际可能返回 false 或错误位置,因为“你”占 3 字节,“好”占 3 字节,“世”也占 3 字节……字节偏移根本对不上字符逻辑。
- 处理中文、日文、韩文、emoji、éàü 等,必须用
mb_strpos,且确保mb_internal_encoding()设为'UTF-8' -
mb_strpos参数顺序和strpos一致,但多一个可选的编码参数:mb_strpos($str, $needle, 0, 'UTF-8') - 没开
mbstring扩展?会报Fatal error: Uncaught Error: Call to undefined function mb_strpos()—— 这个错误得去 php.ini 开扩展,不是代码能绕过去的
查不到?先确认是不是 trim 或编码问题
90% 的“明明写了却找不到”问题,和函数本身无关,而是输入数据有隐藏干扰。
- 字符串前后有空格、BOM、不可见控制符?先
trim($str)再查,或用bin2hex($str)看真实字节 - 文件读入的字符串带换行符?
file_get_contents读出来的可能含\r\n,影响匹配,必要时str_replace(["\r", "\n"], '', $str) - 网页表单 POST 过来的数据被 magic quotes 或旧框架自动转义过?检查
get_magic_quotes_gpc()(已废弃但老环境还存在),或直接stripslashes - 正则需求别硬套
strpos—— 它不支持通配、范围、重复,真要模糊匹配就该换preg_match











