gd扩展未启用、session未初始化或输出缓冲被污染是tp5.0验证码空白的三大主因:gd未启导致entry()静默返回空字符串;session未启使校验值无法存储,check()恒失败;bom/空格/echo等前置输出污染响应体,破坏png二进制流。

GD扩展未启用导致captcha->entry()返回空白
TP5.0 的 Captcha::entry() 依赖 GD 库生成 PNG 图像,如果扩展没开,函数不会报错,而是静默返回空字符串 —— 浏览器看到的就是小叉或空白占位图。
验证方式很简单:php -m | grep gd,没输出就说明没启用。Windows 下要确认 php_gd2.dll 已加载;Linux/Docker 环境常见于镜像默认不装 GD,需手动编译:docker-php-ext-install gd(注意先装 libpng-dev 和 libjpeg-dev)。
改完 php.ini 后必须重启 Web 服务(Apache/Nginx)或 PHP-FPM,仅刷新页面无效。
Session 未初始化导致验证码值写不进、check()永远失败
TP5.0 的验证码校验完全靠 Session 存真实值(比如 session('captcha/1234')),如果 Session 没启动,entry() 虽能输出图片,但后端根本没存码,captcha_check() 必然返回 false。
检查点有三个:
-
application/tags.php中app_init数组是否包含\think\middleware\SessionInit::class -
runtime/session目录是否可写(尤其云服务器常因权限锁死) - 在控制器里加
session('test', 'ok'); var_dump(session('test'));,输出null就是 Session 断了
别信“我开了 session.auto_start”,TP5.0 不认这个,必须走中间件。
输出缓冲被污染:BOM、空格、echo 让图片变乱码
验证码接口本质是输出二进制 PNG 流,任何前置文本(哪怕一个 UTF-8 BOM 或换行)都会让响应体开头混入 HTML/文本,浏览器直接拒解码,Network 面板里能看到响应体是 “PNG” 开头的乱码。
实操建议:
- 所有 PHP 文件用 VS Code 或 Notepad++ 改为 UTF-8 无 BOM 编码
- 在
verify()方法第一行加ob_end_clean();(TP5.0 常见救急写法) - 禁用
display_errors:在入口文件或方法开头加ini_set('display_errors', 'off'); - 绝对不要在验证码方法里调用
dump()、echo、var_dump()或return view()
TP5.0 特有坑:composer 安装错版本导致类找不到
TP5.0 只兼容 topthink/think-captcha 的 1.* 版本,但 composer require topthink/think-captcha 默认装 2.0+(那是 TP5.1+ 专用),结果运行时报 Class 'think\captcha\Captcha' not found。
正确安装命令是:composer require topthink/think-captcha:^1.0。装完检查 vendor/topthink/think-captcha/src/Captcha.php 是否存在,且命名空间是 think\captcha 而非 thinkcaptcha(旧版 TP5.0 用后者,新版统一为前者)。
顺带一提:TP5.0 的 captcha_src() 助手函数依赖配置文件 config/captcha.php,哪怕只写空数组也得存在,否则模板解析会崩。
真正卡住人的,往往不是代码逻辑,而是 GD 没启、Session 中间件漏配、文件带 BOM 这三样 —— 它们不出错,只让图片变空白,查日志也没线索。动手前先直访验证码 URL(如 /index.php/index/verify),看响应体是乱码、HTML 还是 404,比瞎猜快十倍。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











