ThinkPHP 的密钥配置在 config/app.php 的 'key' 字段(TP6/7)或 'crypt_key'(TP5.1),需严格满足32位或16位长度要求,通过 php think key:generate 生成,禁用硬编码与常量定义。

ThinkPHP 的密钥在哪配?不是写在代码里
ThinkPHP 本身没有叫 密钥 的独立配置项,所谓“密钥”实际指代的是加密相关的核心配置:主要是 app.key(用于对称加密如 Cookie、Session 加密)和 app.crypt_key(部分版本或自定义加密场景用)。它不靠手写函数生成后硬编码进控制器或模型,而是统一放在应用配置中。
常见误区是试图在 index.php 或某个控制器里调用 md5(time().rand()) 生成一串字符串赋值给某个变量——这既不安全也不生效。真正起作用的只有框架启动时读取的配置值。
TP6/TP7 怎么设置 app.key?看 config/app.php
ThinkPHP 6 和 7 默认使用 config/app.php 中的 key 字段作为加密密钥。这个值必须是 32 位长的字符串(AES-256-CBC 要求),否则运行时会报错:openssl_encrypt(): Key length error。
- 手动设置:直接修改
config/app.php中的'key' => 'your_32_length_string_here_12345678' - 推荐生成方式:终端执行
php think key:generate(TP6+ 自带命令),自动写入配置并输出结果 - 不要用中文、空格、特殊符号;避免用时间戳、用户名等可预测内容
- 上线后禁止提交明文密钥到 Git,应通过环境变量覆盖:
'key' => $_ENV['APP_KEY'] ?? 'fallback'
为什么改了 key 后 Cookie 全失效?这是正常现象
app.key 变更会导致所有依赖它的加密数据无法解密,包括:think_cookie、PHPSESSID(若开启加密 Session)、cache 中的加密缓存项。这不是 bug,是设计使然。
立即学习“PHP免费学习笔记(深入)”;
- 开发阶段频繁重置 key 可以接受;生产环境严禁随意改动
- 若需平滑迁移,得配合旧 key 解密 + 新 key 重新加密的双密钥逻辑(需自行扩展
think\facade\Crypt) - Session 存数据库或 Redis 时,如果用了
session.encrypt = true,同样受此影响
TP5.x 的 crypt_key 和 app.key 是啥关系?
ThinkPHP 5.1 使用的是 app.crypt_key(位于 config/app.php),长度要求是 16 位(对应 AES-128-CBC)。而 TP6+ 统一收归为 app.key 并强制 32 位。两者不兼容,升级时必须重设。
如果你在 TP5 项目里看到类似 Crypt::setKey('xxx') 的调用,说明用了手动覆盖逻辑——这种写法在 TP6+ 已废弃,Crypt 类不再允许运行时改 key,只认配置值。
最易被忽略的一点:有些老教程教你在 common.php 里写 define('APP_KEY', 'xxx'),这在 TP6+ 完全无效,框架根本不读这个常量。











