验证码校验失败主因是session未启用,需启用sessioninit中间件、确认gd/openssl扩展开启、避免跨域与缓存干扰,并注意输入处理细节。

验证码校验失败在 ThinkPHP6 中非常常见,但绝大多数情况跟代码逻辑无关,而是环境配置或调用链断裂导致。核心问题就一个:session 没真正启用,原始验证码值根本没存进去,check() 当然永远 false。
确认 Session 中间件已启用
TP6 默认不自动初始化 session,哪怕你写了 session_start() 也没用——框架会忽略它。
- 打开
app/middleware.php,找到\think\middleware\SessionInit::class - 删掉该行开头的
//注释,确保它被加载 - 验证是否生效:在控制器里写
session('test', 'ok'); var_dump(session('test'));,输出string(2) "ok"才算成功
检查 GD 和 OpenSSL 扩展是否启用
think-captcha 依赖这两个扩展绘图和部分校验逻辑,缺一不可。
- 执行
composer require topthink/think-captcha - 检查
php.ini中这两行已取消注释:extension=gd、extension=openssl - 改完必须重启 Web 服务(如
php think run或 Apache/Nginx) - 快速验证:控制器中写
var_dump(extension_loaded('gd'));,输出bool(true)才算通过
排除跨域与缓存干扰
前后端域名不一致(比如前端 http://localhost:5173,后端 http://127.0.0.1:8000),Session ID 就不同,校验必失败。
- 开发阶段统一用同域名访问(如都走
localhost) - 验证码图片 URL 必须带防缓存参数,例如:
src="{:captcha_img()}?t=" + Math.random() - 用浏览器开发者工具看网络请求,确认返回状态是 200,Content-Type 是
image/png
校验时注意输入处理细节
验证码默认区分大小写,且一旦被 check() 调用就会自动销毁,不能重复使用。
- 用户输入前先
trim()去除空格 - 比对时建议忽略大小写:
captcha_check($input, '', true)(第三个参数为true表示不区分大小写) - 生成时也可限制字符集,避免混淆,例如配置
'codeSet' => '1234567890'只用数字 - 不要在控制器中直接
return Captcha::create()之外再有其他输出(包括空格、echo、var_dump),否则图像损坏
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











