PHP计算中文字符串长度的方法详解:UTF-8与GBK编码处理
在使用 PHP 处理文本时,常遇到中英文混合或纯中文的字符串,直接调用 strlen 往往因为编码(UTF-8/GBK)占用字节数不同而得到错误的“字符数”。本文将解析底层原理,并提供基于 mbstring 扩展、正则表达式等多种准确的字符串长度计算方案。
为什么直接使用 strlen 计算中文长度不准确?
strlen() 函数统计的是字符串所占的字节(Byte)数,而非字符个数。不同编码格式下,英文与中文占用的字节数差异巨大:
- UTF-8 编码:通常一个英文字符占 1 个字节,一个中文字符占 3 个字节(常见于大多数现代 Web 应用)。
- GBK/GB2312 编码:通常一个英文字符占 1 个字节,一个中文字符占 2 个字节。
例如,在处理 UTF-8 编码的中文字符串时,如果用户输入 "Hello中国",strlen 返回的长度会是 5 + 6 = 11,这显然不符合直观上的字符计数预期。
准确计算字符串长度的推荐方案
第1步:使用 mbstring 扩展(推荐且最准确)
如果你使用的是包含中文内容的现代站点,强烈建议启用 PHP 的 mbstring 扩展。该扩展提供了多字节安全函数,能自动识别编码并返回正确的字符数量。
操作入口:确保服务器已安装并启用 php-mbstring 模块。
核心动作:使用 mb_strlen() 并指定编码参数。
// 获取字符串的字符数,指定编码为 UTF-8
$zhStr = '您好,中国!';
// $enStr = 'Hello!';
$charLen = mb_strlen($zhStr, 'UTF-8');
echo $charLen; // 输出:6 (即3个汉字+3个标点符号=6个字符单元)
// 获取字节数(等同于 strlen 但更安全)
$byteLen = mb_strlen($zhStr, 'current');
完成状态判断:执行结果等于实际可见的字符个数。
第2步:不依赖扩展时的正则匹配方案(UTF-8专用)
若环境受限无法开启 mbstring 扩展,可以使用 preg_match_all 将 UTF-8 字符串拆解为独立的字符单元。此方法仅适用于 UTF-8 编码。
操作入口:编写自定义辅助函数。
核心动作:
利用 /./us 正则表达式匹配所有 Unicode 字符单元。
$zhStr = '您好,中国!';
$str = 'Hello,中国!';
function utf8_strlen($string = null) {
// /us: u代表修正PCRE默认行为按字节处理,s代表让点号(.)匹配包括换行符在内的所有字符
preg_match_all("/.+/us", $string, $match);
return count($match[0]);
}
echo utf8_strlen($zhStr); // 输出:6
echo utf8_strlen($str); // 输出:9
重要参数:u 修饰符至关重要,否则 UTF-8 的多字节字符会被错误地拆分为多个单字节。
第3步:手动遍历 ASCII 值判断(兼容性最强)
如果连 pcre 扩展都不可用(极罕见),可以通过循环读取每个字节的 ASCII 值来判断是单字节字符还是多字节字符的开始。
操作入口:使用 ord() 和循环逻辑。
核心动作:
检查字节数值范围。大于 127 即为非 ASCII 字符(通常是中文)。根据 UTF-8 规范,第一个字节的大小决定了该字符后续跟随几个字节(3字节开头通常在 192-223 或 224-239 等区间)。
function get_char_count_utf8($str) {
$count = 0;
for ($i = 0; $i < strlen($str); $i++) {
$value = ord($str[$i]);
if ($value > 127) {
$count++;
// 跳过该字符剩余字节
if ($value >= 224 && $value <= 239) $i += 2;
elseif ($value >= 192 && $value <= 223) $i += 1;
} else {
$count++;
}
}
return $count;
}
GBK 编码下的特殊处理
GBK 编码下每个中文字符固定占 2 个字节。虽然也可以用上述的正则方法(因为GBK也是单字节语言的一种变体,但需注意正则效率可能略低),但在传统 CMS 或遗留系统中,更常见的做法是直接除以 2,或者借助 mb_convert_encoding 先将 GBK 转为 UTF-8 再进行标准处理。
// GBK 环境下获取字符数
$gbk_str = '你好世界';
$len_byte = strlen($gbk_str); // 结果为 8
$len_char = round($len_byte / 2); // 结果为 4
总结与避坑指南
在处理涉及多语言的 Web 项目时,请务必遵循以下原则:
- 首选 mbstring:
mb_strlen($str, 'UTF-8')是行业标准做法,性能较好且不易出错。 - 统一编码:建议在数据库和应用程序层面统一使用 UTF-8 (UTF-8mb4),避免在代码中进行频繁的 GBK 转码。
- 注意正则细节:如果使用
/./s处理 UTF-8,必须加上u标志,否则在包含 Emoji 或多字节组合字符时仍会报错或计算错误。
以上就是 PHP 计算字符串长度包含中文字符处理的详细内容,更多关于 PHP 字符串操作技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













