strlen() 按字节计数,希腊字母在 UTF-8 中占 2 字节,故 strlen("α") 返回 2;应使用 mb_strlen($str, 'UTF-8') 获取真实字符数,并确保数据库、前端、连接层全链路 UTF-8(utf8mb4)一致,正则需用 \p{Greek} 和 u 修饰符。

strlen() 会把希腊字母算成多个字节
PHP 默认的 strlen() 函数按字节计数,不是按字符。希腊字母(如 α、β、γ)在 UTF-8 编码下占 2 字节,所以 strlen("α") 返回 2,而不是你预期的 1。这在表单验证、截取显示、数据库字段长度校验时容易出错。
常见错误现象:
– 表单限制“最多 10 个字符”,用户输入 6 个希腊字母就被截断
– substr($str, 0, 5) 切出乱码,因为从中间字节断开
– MySQL 插入失败,提示 “Data too long for column”,实际字符数没超但字节数超了
用 mb_strlen() 替代 strlen() 才算真正字符数
mb_strlen() 是多字节安全的字符串长度函数,必须显式指定编码(推荐 'UTF-8'),它才能正确识别希腊字母、中文、emoji 等 Unicode 字符。
- 确保 PHP 启用了
mbstring扩展(绝大多数现代环境已默认启用) - 调用时必须传第二个参数:例如
mb_strlen($str, 'UTF-8'),漏掉编码参数可能导致结果不稳定 - 若字符串来源不可控(如 POST 数据),先用
mb_convert_encoding($str, 'UTF-8', 'auto')做一次归一化更稳妥
示例对比:strlen("αβγ") → 6mb_strlen("αβγ", 'UTF-8') → 3
立即学习“PHP免费学习笔记(深入)”;
数据库和前端也要保持 UTF-8 一致
只改 PHP 测长没用——如果 MySQL 表字段是 latin1 或连接未设 UTF-8,希腊字母存进去就变形;前端 缺失也会导致提交乱码。
- MySQL 连接层需执行
SET NAMES utf8mb4(注意是utf8mb4,不是utf8,后者不支持 4 字节 emoji) - 字段定义推荐
VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - PHP 输出前可加
header('Content-Type: text/html; charset=utf-8');防止浏览器误判编码
正则匹配希腊字母时别用 . 或 \w
写验证逻辑时,比如“只允许希腊字母和数字”,别直接用 /^[a-zA-Z0-9]+$/u——a-zA-Z 完全不覆盖希腊字母。Unicode 属性才是正解。
正确写法:preg_match('/^[\p{Greek}\p{Nd}]+$/u', $str)
其中 \p{Greek} 匹配所有希腊字母(含大小写、带重音符号的变体),\p{Nd} 匹配任意 Unicode 数字(包括阿拉伯数字、罗马数字等)。
注意:
– 正则末尾必须加 u 修饰符,否则 \p{...} 不生效
– \w 在 u 模式下虽会包含希腊字母,但它还包含下划线、连接符等,语义不精确,不建议用于白名单校验
u 修饰符——这两处一漏,前面所有 mb_strlen() 都白做了。











