optimize:config 不重载 .env,仅固化当前内存配置;改 .env 后须先 clear:config 清缓存、确保 env() 调用、CLI 下手动加载 .env 才生效。

optimize:config 不会重新读取 .env,它只把当前已加载的配置写进 runtime/config.php。改了 .env 之后直接跑 php think optimize:config,等于把“旧的、没更新的配置”再缓存一遍——当然没变化。
为什么 optimize:config 不触发 .env 重加载
ThinkPHP 的配置加载是一次性行为:在 App 初始化早期(bootstrap/app.php 阶段)调用 load_dotenv() 解析 .env,之后所有 env() 调用都基于这次解析结果。而 optimize:config 只是把内存里已有的配置数组序列化写入 runtime/config.php,它不重启初始化流程,也不重新 parse .env 文件。
-
optimize:config的作用是“固化当前配置”,不是“刷新环境变量” - 如果你先改了 .env,但没清掉旧的
runtime/config.php,那即使后续调用optimize:config,它读的仍是上次初始化时从旧 .env 解析出的值 - CLI 模式下尤其明显:
php think run启动后,.env 已加载完毕;此时再改文件,不重启进程就无效
改了 .env 后必须做的三件事
缺一不可,顺序不能错:
- 确认
.env文件保存为UTF-8 无 BOM编码(Windows 记事本极易踩坑) - 执行
php think clear:config—— 它会删掉runtime/config.php,强制下次请求重新初始化并加载 .env - 确保 config/*.php 中每个字段都用了
env('KEY', 'default')形式,比如'hostname' => env('DB_HOST', '127.0.0.1');光写DB_HOST=xxx在 .env 里,但配置文件里没调env(),照样无效
CLI 环境下 .env 加载失败的典型表现
运行 php think migrate 或 php think clear:config 时,env('DB_HOST') 返回 null 或默认值,但 getenv('DB_HOST') 却有值——这说明 .env 文件被系统读到了,但 ThinkPHP 的 Env 类没加载成功。
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP 8 默认只在 Web 入口(
public/index.php)自动加载 .env,CLI 下需手动补加载逻辑 - 检查项目根目录下的
think文件末尾是否加了:if (PHP_SAPI === 'cli') { \Dotenv\Dotenv::createImmutable(__DIR__)->safeLoad(); } -
__DIR__必须指向项目根目录(含app/、config/、.env),不是public/或vendor/ - 如果用了白名单机制(如
Env::setWhitelist()),记得把自定义 KEY(如DB_HOST)加进去,否则Env::get()会静默返回 null
最常被忽略的一点:你以为改完 .env 就完事了,其实框架根本没“看见”新内容——它早就在第一次初始化时把旧值锁进缓存了,而 optimize:config 只是把这个锁定状态再存一次。



















