直接使用topthink/think-captcha扩展包即可,无需手写GD逻辑;需在项目根目录执行composer require topthink/think-captcha安装,确保session开启,验证码生成用Captcha::create()(非entry),校验用Captcha::check(),注意大小写敏感、过期时间及配置覆盖问题。
直接用
就行,别自己手写 GD 逻辑,除非你真要控制每个像素——但绝大多数项目根本不需要那么深的定制。
安装 think-captcha 扩展包必须用 Composer
ThinkPHP 6 默认不带验证码功能,得单独装扩展。命令只有一条:
注意两点:
别在
目录下执行,得在项目根目录(即有
的地方)
如果报错说找不到包,先确认是否已配置国内镜像:
或改用阿里云源
装完后无需手动注册服务提供者——ThinkPHP 6+ 自动发现并加载
生成验证码要用
而不是
很多老教程写
,那是 ThinkPHP 5.x 的写法,TP6 已废弃。现在标准流程是:
立即学习
“
PHP免费学习笔记(深入)
”;
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
控制器里调用
,它会自动输出图片并把验证码值存进 session
返回值是
对象,不能直接 return 字符串或数组,否则图片无法渲染
路由必须是独立接口,比如
,不能塞在页面渲染逻辑里(否则响应头冲突)
示例代码:
校验失败的常见原因
用户输对了还是提示“验证码错误”,八成是下面几个点没对上:
session 没开启:检查
是否被禁用,或配置里
路径不可写
大小写敏感:默认
包含大小写字母,但前端输入框没限制 type="text",用户可能输成全大写,而服务端比对是严格匹配的
过期时间不一致:
配置单位是秒,设成
表示 1 分钟,但用户拖太久再提交就失效;别设成 0 或负数,那等于立刻过期
多次调用
:每次调用都会覆盖 session 里的旧值,如果页面加载时触发一次、用户点击刷新又触发一次,第一次的验证码就作废了
自定义配置别只改
就完事
配置文件生效的前提是:你没在代码里传入新配置覆盖它。比如:
如果写了
,那
里的
就被无视了
和
开关要一起开才有明显效果,单开一个干扰太弱,OCR 工具几行 Python 就能绕过
字体文件路径要绝对可靠:如果指定
,得确保该路径在 CLI 和 Web 环境下都可读,否则图像生成失败但无报错,只返回空白图
别把
/
设得太小(如
),移动端点击区域太小,用户容易误点刷新
真正容易被忽略的是:验证码图像生成后,session 中存的是明文(比如
),不是 hash。这意味着只要 session 被窃取,验证码就等于白设——所以别在公共 WiFi 下做高敏操作,这不是框架能解决的问题。
topthink/think-captchacomposer require topthink/think-captchathinkphp/frameworkcomposer.jsoncomposer config -g repo.packagist https://packagist.phpcomposer.comthink-captchaCaptcha::create()entry()$captcha->entry()Captcha::create()Response/captchause think\captcha\Captcha;
class IndexController extends Controller
{
public function captcha()
{
return Captcha::create();
}
}Captcha::check()session_start()'type' => 'file'codeSetexpire60create()config/captcha.phpCaptcha::create(['length' => 6])config/captcha.php'length' => 4useNoiseuseCurve'fontttf' => './public/fonts/1.ttf'imageWimageH80x30"aB3x"