必须用mb_strlen处理中文:strlen返回字节数(如"你好"得6),mb_strlen才返回字符数(得2),且须启用mbstring扩展并显式指定'UTF-8'编码。

PHP字符串函数不是“怎么用”的问题,而是“在哪种场景下必须换另一个用”——多数报错和乱码,根本不是函数不会用,是没意识到 strlen 和 mb_strlen 处理中文时返回的是两种东西。
处理中文时,strlen 返回字节数,mb_strlen 才返回字符数
UTF-8 下一个汉字占 3 字节,strlen("你好") 返回 6,但你真正想问的往往是“这个字符串有几个字”,答案是 2。这时候必须用 mb_strlen("你好", 'UTF-8')。不指定编码参数或没启用 mbstring 扩展,mb_strlen 会静默失败或返回 0。
-
mbstring扩展必须开启,否则所有mb_*函数不可用(检查phpinfo()或运行extension_loaded('mbstring')) - 编码参数不能写成
'utf8',必须是'UTF-8'(注意连字符和大小写) - 如果只是做简单长度校验(比如限制用户名≤10字符),用
mb_strlen;如果做二进制协议解析或计算内存占用,才用strlen
strpos 返回 0 时,== false 会误判,必须用 !== false
查找子串开头就匹配,比如 strpos("apple", "a") 返回 0,但 if (strpos($str, $needle) == false) 会把它当成“没找到”。这是 PHP 类型隐式转换最常踩的坑之一。
- 永远用严格比较:
if (strpos($str, $needle) !== false) - 需要忽略大小写时,别自己转大小写再查,直接用
stripos,它也返回位置或false,同样要!== false - 找最后一次出现的位置用
strrpos,不是strrev + strpos,后者在多字节字符串里会截断乱码
substr 截中文可能出乱码,mb_substr 才安全
substr("你好世界", 0, 3) 在 UTF-8 下极大概率返回乱码,因为强行按字节切,把某个汉字的中间两个字节拿出来了。而 mb_substr("你好世界", 0, 3, 'UTF-8') 按字符切,结果是“你好”。
立即学习“PHP免费学习笔记(深入)”;
-
mb_substr的第四个参数必须显式传编码,不能省略 - 起始位置支持负数(如
-2表示倒数第二个字符),但mb_substr的负数逻辑和substr一致,可放心迁移 - 如果只处理纯 ASCII 输入(比如 token、base64、hex 字符串),
substr更快,不用上mb_*
trim 默认不清理全角空格、零宽字符、BOM
trim 只清理 ASCII 空白符:空格、\t、\n、\r、\0、\x0B。用户从 Word 粘贴的文本、微信转发内容、甚至某些编辑器保存的文件,常含全角空格( )、零宽空格(\u200b)、UTF-8 BOM(\xEF\xBB\xBF),这些 trim 一概无视。
- 清理全角空格:用
str_replace(' ', '', $str)单独处理 - 清理零宽字符:正则
preg_replace('/[\x{200B}-\x{200D}\x{FEFF}]/u', '', $str) - 去 BOM:可用
ltrim($str, "\xEF\xBB\xBF"),但更稳妥是读取时检测并跳过
真正麻烦的从来不是“有没有函数”,而是你不知道某个函数在什么边界条件下会失效——比如 explode 遇到空分隔符会警告,str_replace 数组参数顺序反了就替换错,htmlspecialchars 不设 ENT_QUOTES 和编码会导致单引号不转义。这些细节不写进日志、不跑异常路径,根本发现不了。



















