config:cache 缓存的是 config/ 目录下纯 PHP 数组文件合并后的结果,仅快照 env() 值,不缓存运行时依赖或动态配置,错误写法会导致静默逻辑异常。

配置缓存不是“开了就快”,而是必须满足静态性、可序列化、无运行时依赖三个硬条件,否则缓存后反而出错或失效。
config:cache 命令到底缓存了什么
它只读取 config/ 目录下所有返回纯 PHP 数组的文件(如 app.php、database.php),把它们合并写入 bootstrap/cache/config.php。这个文件是直接 require 执行的数组,不经过任何解析逻辑。
- 不会缓存
.env文件本身,但会把env()调用的结果“快照”下来——也就是说,执行config:cache时STRIPE_KEY是什么值,缓存里就固定成什么值 - 不会缓存第三方包在服务提供者中动态注册的配置(比如某些 SDK 的
boot()方法里调用Config::set()) - 不会缓存含
app()->environment()、request()、session()等运行时函数的配置项,这些在缓存后会变成死值
哪些配置写法会导致 config:cache 失败或行为异常
常见错误不是语法报错,而是缓存后逻辑“静默错乱”,比如本地调试正常,上线后环境判断永远为 true。
-
'debug' => app()->environment('local')→ 缓存后永远是执行命令时的环境判断结果,跟当前APP_ENV无关 -
'log_level' => $_SERVER['APP_LOG_LEVEL'] ?? 'error'→$_SERVER在缓存生成时可能为空,导致线上日志级别被锁死 -
'services' => ['mailgun' => ['domain' => env('MAILGUN_DOMAIN')]]→ 这种嵌套写法没问题,但若写成'domain' => env('MAILGUN_DOMAIN') ?: config('app.url'),后者config()在缓存阶段尚未加载,会报错
开发与部署中 config 缓存的正确节奏
缓存不是一次性操作,而是一套状态管理流程。关键在于“清”和“生”的顺序不能颠倒,且必须匹配当前代码状态。
- 每次修改
.env或任意config/*.php后,先运行php artisan config:clear,再运行php artisan config:cache - CI/CD 部署脚本中,务必在
composer install --no-dev --optimize-autoloader之后再执行config:cache,否则可能因类未加载而失败 - 不要在生产环境手动执行
config:clear后跳过config:cache—— 此时应用会退回到未缓存模式,但env()可能已不可用(尤其当 Dotenv 被跳过时),导致config()返回空或报错
怎么验证 config 缓存是否生效且安全
不能只看文件是否存在,要确认内容结构和运行时行为一致。
- 检查
bootstrap/cache/config.php是否为合法 PHP 数组,开头是<?php return [,结尾是]; - 在
tinker中执行config('app.name')和config('database.connections.mysql.host'),确认返回值与.env和对应配置文件一致 - 运行
php -r "var_dump(is_array(config()));",输出bool(true)表示缓存已加载;若为null或false,说明缓存未生效或损坏 - 特别注意:缓存后
config(['app.name' => 'New'])写操作会被忽略,这是预期行为,不是 bug
最常被忽略的是缓存生成时机与环境变量快照的关系——config:cache 不是“启用缓存”,而是“固化当前配置快照”。一旦在 staging 环境生成了缓存,再部署到 production,里面混着 staging 的 DB_HOST 就很危险。所以缓存命令必须在目标环境上执行,不能跨环境复用 config.php 文件。


















