根源是字体文件不支持中文且字符集未对齐:必须用含中文glyph的ttf字体(如simhei.ttf)、php脚本与字符串均为utf-8无bom、imagettftext()传入绝对路径及utf-8字节流。

PHP验证码图片输出中文乱码的根源是字符集不匹配
根本问题不在“加编码”本身,而在 GD 图像绘制时用的字体文件不支持中文,或 PHP 脚本、HTTP 响应头、浏览器解析三者之间字符集未对齐。单纯在 header() 里加 charset=utf-8 或给 imagepng() 加 BOM 都无效——GD 不读取 HTTP 编码声明,它只认字体里的字形和传入的字符串字节序列。
必须用支持中文的字体文件(.ttf)并显式指定路径
系统默认字体(如 arial.ttf)基本不含中文 glyph,imagettftext() 遇到中文会静默渲染为空白或方块。你得提供一个真实含 GB2312/UTF-8 中文的 TTF 文件,并确保 PHP 进程有读取权限。
-
imagettftext()第五个参数必须是绝对路径,相对路径常因 CLI/web 目录差异失效,推荐用__DIR__ . '/simhei.ttf' - 字体文件建议选
simhei.ttf(黑体)、msyh.ttf(微软雅黑)或开源的NotoSansCJKsc-Regular.otf - 用
mb_strlen($text, 'UTF-8')校验字符串长度,避免 UTF-8 多字节被当单字节截断 - 若开发环境显示正常但线上乱码,先检查服务器是否真有该字体文件,而非仅本地存在
PHP 脚本自身编码、输入文本、HTTP 头需保持 UTF-8 一致
脚本保存为 UTF-8 无 BOM 格式;验证码文本生成逻辑中不能用 rand() 拼接 GBK 编码的字库数组;输出前必须清除所有输出缓冲,再发正确的 Content-Type 头。
- 脚本开头加
mb_internal_encoding('UTF-8');统一多字节函数默认编码 - 中文字符来源必须是 UTF-8 字符串,例如:
$chars = '零一二三四五六七八九十';(直接写汉字,别用iconv('GBK', 'UTF-8', ...)动态转) - 输出图片前严格调用:
header('Content-Type: image/png');—— 不要加; charset=utf-8,MIME 类型里不带 charset - 确保没其他代码(包括空格、BOM、
echo)在header()前输出,可用ob_clean()强制清理缓冲
浏览器加载验证码图片时不会继承页面 charset,靠的是响应头和图片内嵌信息
HTML 页面的 <meta charset="UTF-8"> 对 <img src="verify.php" alt="PHP怎么加编码_PHP验证码图片含中文乱码加编码怎么调【说明】" > 完全无效。浏览器解析图片只看 HTTP 响应头中的 Content-Type 和图片数据本身。所以重点不是“页面编码”,而是 verify.php 输出时是否干净、是否用了正确字体、是否传了 UTF-8 字节流给 imagettftext()。
立即学习“PHP免费学习笔记(深入)”;
- 调试时用 curl 直接请求 verify.php:
curl -I http://yoursite.com/verify.php,确认返回Content-Type: image/png且无text/html - 若返回的是 HTML 错误(如 500),说明 PHP 报错被输出了,必须关掉
display_errors或捕获异常 - Windows 服务器要注意:某些字体文件名含中文或空格时,
file_exists()可能返回 false,统一用英文名+下划线











