strlen() 返回错误长度是因为它按字节计数,而泰文在UTF-8中占2–3字节/字符,如"สวัสดี"返回12而非6;应使用mb_strlen($str, 'UTF-8')替代。

strlen() 在泰文字符串上为什么返回错误长度
strlen() 是 PHP 的单字节计数函数,它把每个字节都算作一个字符。泰文属于 UTF-8 编码下的多字节字符(常见为 2–3 字节/字符),所以 strlen("สวัสดี") 返回 12 而不是 6 —— 它数的是字节,不是“人眼看到的字”。这在表单校验、截取显示、数据库字段长度限制等场景下会直接导致逻辑错误。
mb_strlen() 是正确解法,但必须指定编码
PHP 的 mb_strlen() 支持多字节编码识别,但默认编码依赖 mb_internal_encoding() 设置,而该设置未必是 UTF-8(尤其老项目或未显式配置时)。不指定编码参数极易踩坑:
- ✅ 正确写法:
mb_strlen($str, 'UTF-8') - ⚠️ 危险写法:
mb_strlen($str)(依赖当前内部编码,不可靠) - ❌ 错误写法:
mb_strlen($str, 'GBK')(泰文在 GBK 中无法表示,返回 false 或 0)
示例:mb_strlen("สวัสดีครับ", 'UTF-8') 稳定返回 9;strlen("สวัสดีครับ") 返回 21。
截取泰文字符串别用 substr(),改用 mb_substr()
用 substr() 截泰文大概率产生乱码,因为可能在某个字符的中间字节处切断。比如 substr("สวัสดี", 0, 5) 可能输出 สัสดี——前两个字节不属于完整 UTF-8 序列。
立即学习“PHP免费学习笔记(深入)”;
- 始终用
mb_substr($str, $start, $length, 'UTF-8') - $length 参数单位是字符数,不是字节数
- 若 $length 为 null,则截取到末尾(
mb_substr($str, 2, null, 'UTF-8')) - 注意:$start 也是按字符偏移,不是字节偏移
判断是否含泰文字符可结合正则与 mb_ 函数
单纯靠长度判断不够,有时需确认字符串里真有泰文。Unicode 中泰文范围是 \u0E00-\u0E7F,但要注意:PHP 的 PCRE 默认不支持 Unicode 属性(如 \p{Thai}),除非启用 u 修饰符且确保 PCRE 版本 ≥ 8.32。
- 推荐兼容写法:
preg_match('/[\x{0E00}-\x{0E7F}]/u', $str) - 更稳妥的检测方式:
mb_ereg('[\x0E00-\x0E7F]', $str)(但mb_ereg已废弃,慎用) - 实用组合判断:
mb_strlen($str, 'UTF-8') !== strlen($str) && preg_match('/[\x{0E00}-\x{0E7F}]/u', $str)(排除其他多字节语言干扰)
真正容易被忽略的是:很多泰国用户会混输英文、数字和空格,这些仍是单字节;所以「含泰文」不等于「全泰文」,业务逻辑中要区分清楚。











