gd库未启用、输出被缓存污染或thinkphp版本升级导致captcha类行为变化是验证码乱码或500错误的主因;需启用gd扩展、entry前加ob_clean()、tp6改用think-captcha扩展并更新配置与调用方式。

验证码图片返回一堆乱码、空白或 500 错误,基本不是代码写错了,而是 GD 库没开、输出被缓存污染、或 ThinkPHP 版本升级后 Captcha 类行为变了。
GD 库未启用是头号原因
TP5/TP6 验证码依赖 PHP 的 GD 图像处理能力生成 PNG/JPEG。如果 phpinfo() 里搜不到 gd,或者 extension=php_gd2.dll(Windows)或 extension=gd.so(Linux)在 php.ini 中被注释或缺失,Captcha::entry() 就会直接输出原始二进制数据,浏览器解析成乱码。
- Windows 下打开
php.ini,取消;extension=php_gd2.dll前的分号;Linux 下执行sudo apt install php-gd或yum install php-gd - 改完必须重启 Web 服务(
apache2或php-fpm),仅刷新页面无效 - 验证方式:新建
test.php,写<?php echo extension_loaded('gd') ? 'ok' : 'fail'; ?>,访问看输出
ob_clean() 必须加在 entry() 前
TP5 升级到 TP6 后,部分中间件或日志组件会在响应前写入缓冲区(比如调试信息、BOM 头、空格),导致 Captcha::entry() 输出的图像流前面混入了文本,浏览器拒绝渲染,显示为破损图或下载提示。
- 在控制器中调用验证码入口时,务必在
$captcha->entry()前加ob_clean(); - 不要用
ob_end_clean(),它可能提前关闭缓冲区,导致后续输出失败 - 如果用了
think-captcha扩展包(v3+),其CaptchaController已内置ob_clean(),但自定义路由或手动实例化仍需自行加
TP6 使用 think-captcha 时路径和配置变更
TP6 官方不再内置 Verify 类,改推独立扩展 topthink/think-captcha。旧项目升级后若沿用 \think\captcha\Captcha,会因命名空间或类加载路径错误导致 500 或白屏。
- 执行
composer require topthink/think-captcha安装最新版(当前 v3.0.11+) - 模板中不再写
{:captcha_img()},应改为{:captcha_src()}(v3 起函数名变更) - 配置文件从
config/verify.php移至config/captcha.php,且默认字体路径已指向vendor/topthink/think-captcha/assets/zhttfs.ttf - 若自定义字体,确保路径可读,且字体文件真实存在——TP6 不再静默降级,缺字体会直接抛出
InvalidArgumentException
Session 未启动或 domain 不匹配导致校验失败
验证码图片能显示,但提交后总提示“验证码错误”,大概率是 Session 数据根本没写进去,或写进去了却读不到。常见于 Nginx 反向代理、多级子域名、HTTPS 混合部署场景。
- 检查
config/session.php中domain是否为空或设错,例如站点是user.example.com,但domain写成.example.com可能被浏览器拒绝发送 Cookie - 确认
session_start()确实被执行:TP6 默认开启 session 中间件,但如果在middleware.php中误删了SessionInit,或在验证码接口路由上显式关闭了中间件,就会失效 - 用浏览器开发者工具的 Application → Cookies 查看是否存有
PHPSESSID,并确认请求头中是否携带该 Cookie
最易被忽略的是:TP6 的 think-captcha v3 默认启用 useZh(中文验证码),若未提供中文字体或禁用失败,会静默 fallback 到英文但不报错,而你前端传参仍按中文逻辑处理,结果就是“看着有图、输对也错”。遇到怪异校验失败,先关掉 useZh 测试。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











