正确方式是先清除BOM及空白符再输出PNG:用UTF-8无BOM编码保存文件,确保header前无任何输出;验证码应使用显式安全字符集如'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'避免易混字符。

PHP生成PNG格式验证码图像的正确方式
直接用 imagepng() 输出验证码 PNG 图像没问题,但必须确保输出前未发送任何 HTTP 头(包括空格、BOM、echo、print),否则浏览器会提示“损坏的图像”或显示空白。
为什么 header("Content-type: image/png") 之后还报错?
常见原因是 PHP 文件本身含 UTF-8 BOM(尤其 Windows 编辑器保存时默认添加),或在 header() 前存在不可见字符。验证方法:用 hexdump -C your_captcha.php | head 查看开头是否有 ef bb bf;修复方法:用 VS Code / Notepad++ 切换为“UTF-8 无 BOM”编码保存。
验证码字母不区分大小写且易混淆?这样改
默认用 rand(0, 25) + chr(65 + $n) 会生成全大写 A–Z,但 0/O、1/l/I 容易看错。建议显式定义安全字符集,并禁用易混字符:
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // 去掉 0,O,1,l,I
$code = '';
for ($i = 0; $i < 4; $i++) {
$code .= $chars[rand(0, strlen($chars) - 1)];
}session_start() 必须在 imagepng() 之前调用
验证码值需存入 session 供后续校验,但 session_start() 若放在图像输出后,会导致 session 写入失败或警告。注意顺序:
立即学习“PHP免费学习笔记(深入)”;
-
session_start()必须是脚本第一行有效 PHP 代码(排除空行和注释) - 生成图像资源(
imagecreatetruecolor()等)和绘制文字后,再调用$_SESSION['captcha'] = $code; -
imagepng()和imagedestroy()放在最后,且中间不能有任何echo/var_dump
最常被忽略的是:验证码图像脚本不应包含 HTML 标签或任何非二进制输出——它就是一张图,多一个换行都会让 PNG 解析失败。



















