
PHP 的字符串本质是字节数组,直接用 $str[1] 访问多字节 UTF-8 字符(如波兰语的 ś、ż、ć)会截断字节序列,导致乱码“”;必须使用 mb_* 多字节函数才能安全操作 Unicode 字符。
php 的字符串本质是字节数组,直接用 `$str[1]` 访问多字节 utf-8 字符(如波兰语的 ś、ż、ć)会截断字节序列,导致乱码“”;必须使用 `mb_*` 多字节函数才能安全操作 unicode 字符。
在 PHP 中处理波兰语等含扩展拉丁字符(如 ś, ż, ć, ń, ł)的 UTF-8 字符串时,一个常见误区是误将字符串当作“字符数组”直接通过下标访问(例如 $str[0] 或 $str[1])。实际上,PHP 的原生字符串操作(包括方括号语法)是以字节(byte)为单位的,而非字符(character)。而 UTF-8 编码中,波兰字符属于多字节序列:例如 'ś' 在 UTF-8 中占用 2 个字节(十六进制为 c59b),'ż' 占用 2 字节(c5bc),'ć' 同样为 2 字节(c487)。
因此,当执行 $nam[1] 时,PHP 并非取出第二个“字符”,而是取出整个字符串的第二个字节——这恰好是 'ś' 的后半部分(如 9b),该字节单独无法构成合法 UTF-8 序列,浏览器渲染时即显示为替换符号 ``。
✅ 正确做法:使用 PHP 的 Multibyte String 扩展(mbstring) 提供的函数,它们能识别 UTF-8 字符边界:
function ech($nam) {
echo htmlspecialchars($nam, ENT_UTF8) . "<br>";
// ✅ 安全获取第一个字符(UTF-8 感知)
echo mb_substr($nam, 0, 1, 'UTF-8') . "<br>";
// ✅ 获取第二个字符(索引从 0 开始)
echo mb_substr($nam, 1, 1, 'UTF-8') . "<br>";
// ✅ 获取长度(按字符数,非字节数)
echo "字符数:" . mb_strlen($nam, 'UTF-8') . "<br>";
echo "字节数:" . strlen($nam) . "<br>";
}
$te = $_POST['sth'] ?? 'śżć'; // 示例输入
ech($te);
输出结果:
śżć<br> ś<br> ż<br> 字符数:3<br> 字节数:6<br>
? 关键注意事项:
- 确保 mbstring 扩展已启用(检查 phpinfo() 或 extension=mbstring 是否在 php.ini 中开启);
- 显式指定编码 'UTF-8' 参数(尤其在 mb_substr/mb_strlen 中),避免依赖默认配置;
- 输出前建议使用 htmlspecialchars($str, ENT_UTF8) 防止 XSS,且确保 HTML 声明 ;
- 切勿混用 substr()/strlen() 与 mb_substr()/mb_strlen() 处理同一 UTF-8 字符串,否则逻辑错乱。
总结:PHP 中没有原生的 Unicode 字符索引支持。只要涉及非 ASCII 字符(包括中文、日文、阿拉伯文、波兰语等),所有字符串操作都应优先选用 mb_* 函数,并始终明确指定 'UTF-8' 编码参数——这是构建国际化 Web 应用的底层基石。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











