thinkphp 的 captcha session 键名硬编码为 'captcha',无法通过配置修改;必须继承 captcha 类并重写 generate() 和 check() 方法,将键名替换为自定义值(如 'my_captcha_v2'),同时同步更新验证器规则和调用方式。

ThinkPHP 的 captcha 验证码校验默认把原始值存进 Session,键名是硬编码的 captcha(不是配置项,不能直接改)。想换键名,必须修改源码或重写验证逻辑——否则所有基于 captcha_check() 或 Captcha::check() 的调用都会失效。
为什么不能通过配置改 Session 键名
官方插件 topthink/think-captcha v3(TP6.1+ 默认)在 Captcha.php 中把键名写死在代码里:
生成时用 $this->session->set('captcha', [...]),
校验时用 $this->session->has('captcha') 和 $this->session->get('captcha.key')。
它**不读取任何配置项来动态拼接键名**,所以改 config/captcha.php 里的任意字段都没用。
如何安全地替换 Session 键名
推荐继承原类并覆盖关键方法,避免直接改 vendor 源码(否则 composer update 会丢失):
- 新建类
app\common\captcha\CustomCaptcha.php,继承\think\captcha\Captcha - 重写
generate()方法:把$this->session->set('captcha', [...])改成$this->session->set('my_captcha_v2', [...]) - 重写
check()方法:把所有'captcha'字符串替换成'my_captcha_v2',包括has()、get()、delete() - 注册为 facade 或绑定到容器,让
captcha_check()助手函数调用你的新类(需重写helper.php中的函数,或统一用新类实例调用)
示例片段:
protected function generate(): string
{
$code = $this->getCode();
$hash = password_hash($code, PASSWORD_BCRYPT, ['cost' => 10]);
// 替换键名
$this->session->set('my_captcha_v2', [
'key' => $hash,
'time' => time(),
]);
return $this->createImage($code);
}
改键名后必须同步处理的三个地方
只改生成逻辑不改校验,等于白改。以下三处必须一一对应:
-
captcha_check($input)助手函数底层仍调用原Captcha::check(),你要么重写这个函数,要么彻底弃用它,改用(new CustomCaptcha())->check($input) - 如果用了验证器规则
'captcha|验证码' => 'require|captcha',这个captcha验证规则是框架内置的,它也硬依赖原键名;必须自定义验证规则,比如MyCaptchaRule,并在其中调用你的新类 - 前端提交的验证码值本身没变,但后端存储位置变了——务必确认没有其他中间件、钩子或自定义逻辑还在读写
'captcha'这个旧键
不建议直接改 vendor 源码的两个原因
一是 composer update 会覆盖掉你的修改,导致线上突然校验失败;
二是 TP 后续小版本可能调整 generate() 或 check() 的参数签名(比如加第四个参数),你的补丁会报错。
真正要改键名,核心就一条:别碰 vendor/,用继承 + 覆盖 + 替换调用链的方式,把“键名”这个耦合点从底层逻辑里拎出来单独控制。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











