php artisan config:cache 将 config/ 目录下所有 PHP 配置文件执行后序列化为 bootstrap/cache/config.php,使 config() 调用直接读取该单文件、跳过多次 I/O 与解析;它不读 .env 实时变化,且要求环境为 production、无闭包或未加载类引用,失败常因语法错误、运行时函数调用或权限问题。

配置缓存不是“设个开关就生效”,必须执行 php artisan config:cache 才真正起作用;不运行这行命令,.env 里改一百遍也没用。
config:cache 命令到底做了什么
它把 config/ 目录下所有 PHP 文件(比如 app.php、database.php)全部加载并执行一遍,把最终得到的纯数组序列化后写进 bootstrap/cache/config.php。后续所有 config('app.name') 都直接从这个单文件读——跳过 20+ 次文件 I/O 和 PHP 解析。
这个文件是合法 PHP 代码,不是 JSON 或 YAML,所以不能手动编辑;一旦生成,config() 就完全忽略原始配置文件和 .env 的实时变化。
-
env()只在生成缓存那一刻求值,之后再改.env无效 - 配置里用了闭包(如
'log' => function () { })会直接报错:无法序列化 - 配置中调用了尚未加载的类(比如
App\MyHelper::value()),缓存阶段 autoloader 还没 ready,也会失败
为什么 config:cache 失败或不生效
常见报错像 Undefined variable: env 或 Class 'App\Providers\AppServiceProvider' not found,本质都是缓存生成时执行了不该执行的代码。
-
.env有语法错误(漏引号、中文等号、换行混乱)→env()返回null→ 依赖它的配置项崩掉 - 配置文件里写了
app()、config()、resolve()等运行时函数 → 缓存阶段上下文不全,挂掉 - 没切到生产环境:
APP_ENV=production没设好 → 开发专用配置(如barryvdh/laravel-debugbar)混进去,引发冲突 - 执行命令时当前目录不是项目根目录 → 找不到
artisan或自动加载器失效
改完配置后必须连着清+重生成
只跑 php artisan config:clear 不够,它只是删掉 bootstrap/cache/config.php;如果不清完就直接访问,Laravel 会退回到逐个 require 原始配置文件的模式——这时若 .env 有错,反而更容易暴露问题。
- 修改
.env后:先php artisan config:clear,再php artisan config:cache - 改了
config/*.php里的值:同样要清+重生成,否则缓存还是旧的 - 部署脚本里漏掉
config:cache,哪怕其他优化全做了,首字节响应时间(TTFB)仍被拖慢 30–80ms - 多服务器部署时,每台机器都得独立执行,别共享
bootstrap/cache/config.php(路径、权限、PHP 版本可能不一致)
缓存后哪些行为会“突然失效”
配置缓存改变了整个配置系统的读取路径和时机,很多你以为安全的操作其实已不起作用。
-
php artisan tinker里执行config(['app.name' => 'test'])是运行时覆盖,只对当前请求有效;重启 tinker 就恢复缓存值 - 代码里写
config(['database.connections.mysql.host' => $host])—— 缓存后这个赋值会被忽略,因为底层是只读数组 - 某些包在服务提供者里动态改配置(比如根据请求头切换 DB 连接),缓存后这部分逻辑根本不会执行
- CI/CD 流程中,
php artisan config:cache必须放在git pull和composer install --no-dev完成之后,否则缓存内容和实际代码对不上
最常被忽略的一点:缓存文件 bootstrap/cache/config.php 是 PHP 可执行代码,web server 进程必须有读权限;但很多人设完就忘——如果部署用户和 web server 用户不一致(比如用 root 部署,nginx 以 www-data 身份运行),就会因权限拒绝导致 500 错误,且日志里未必报得清楚。


















