修改 .env 后迁移不生效,需先运行 php artisan config:clear 清缓存,再执行 migrate;DB_PASSWORD 含特殊字符须用双引号包裹;APP_KEY 不可随意更改,否则引发 DecryptException。

修改 .env 后迁移命令不生效?先清缓存再跑 migrate
执行 php artisan migrate 时连不上数据库,或报错说表已存在但实际没建——大概率是 .env 里改了 DB_DATABASE 或 DB_CONNECTION,但 Laravel 还在用旧的缓存配置。Laravel 的迁移命令会走完整启动流程,包括加载配置,而配置一旦被 config:cache 固化,就不会再读 .env。
实操建议:
- 改完
.env后,**必须**运行php artisan config:clear,再执行php artisan migrate - 如果项目已启用 OPcache(尤其生产环境),还需手动重载 OPcache,否则
config:clear可能不彻底 - 别用
php artisan config:cache来“刷新”——它只会把当前缓存再打包一次,不会重新解析.env - 在 CI/CD 流程中,确保
config:clear在migrate之前,且环境变量注入(如 GitHub Actions 的env:)早于任何配置缓存步骤
APP_ENV 变更后 migrate 读错 config/*.php 文件?检查环境专属配置加载逻辑
Laravel 会根据 APP_ENV 值自动加载 config/database.production.php 这类文件,覆盖默认 config/database.php。但如果你把 APP_ENV=staging 写进 .env,却没提供 config/database.staging.php,迁移仍走默认配置;反之,若文件存在但 APP_ENV 拼错(比如写成 stage),该文件根本不会被加载。
实操建议:
-
APP_ENV必须是 Laravel 认可值:local、staging、production(大小写敏感),否则 Dotenv 不加载,env()返回null - 确认
bootstrap/app.php中保留了Dotenv::createImmutable(__DIR__.'/../')调用,否则环境加载机制失效 - 用
php artisan tinker验证:输入env('APP_ENV')看是否返回预期值;再查config('database.default')是否匹配你期望的连接名 - 迁移前临时加一行
dd(config('database.connections.mysql'));到config/database.php开头,快速确认实际加载的是哪套参数
DB_PASSWORD 含特殊字符导致 migrate 失败?必须用双引号包裹
php artisan migrate 报错 “Access denied for user”,但密码明明对——常见原因是 DB_PASSWORD 值含 #、$、空格等 shell 特殊字符,未加引号导致 Dotenv 解析截断。例如 DB_PASSWORD=p@ss#word 会被当成 p@ss,后面部分被当注释丢弃。
实操建议:
- 所有含
#、$、空格、反斜杠的值,**必须**用双引号包裹:DB_PASSWORD="p@ss#word!" - 不要依赖 IDE 自动补全引号——有些编辑器会帮你加单引号,但 Dotenv 只识别双引号包裹的字符串
- 改完立刻用
php artisan tinker执行env('DB_PASSWORD')验证输出是否完整 - CI/CD 中若用脚本生成
.env,记得对变量值做 shell 转义,或直接用printf '%s=%q\n'生成安全格式
动态改 APP_KEY 后 migrate 报 DecryptException?别碰已加密数据的密钥
执行 php artisan migrate:fresh 或队列迁移时突然抛 DecryptException,不是迁移本身的问题,而是 APP_KEY 被改过。Laravel 用它加密 Cookie、remember_token、队列任务载荷等——只要数据库里存了这些加密内容,换密钥就无法解密,迁移命令在启动阶段就会失败。
实操建议:
-
APP_KEY是项目级密钥,**不可随意更改**。新项目用php artisan key:generate初始化即可 - 已有项目若必须换密钥(如泄露),需同步迁移所有已加密字段:导出旧数据 → 用旧密钥解密 → 用新密钥加密 → 导入,现实中极少操作
- 测试环境可接受风险时,先清空
users表的remember_token、删掉jobs表全部记录,再换密钥 - 别在
.env里手写固定APP_KEY字符串,也别复用其他项目的密钥——密钥熵值不足会导致加密强度下降
最易被忽略的一点:迁移命令本身不改 .env,但它的执行结果(比如新建的数据库)会依赖 .env 的实时状态。任何缓存残留、权限问题、引号缺失或密钥变更,都会让 migrate 在启动阶段就卡住,而不是在 SQL 执行时报错。验证永远从 php artisan tinker + env() 和 config() 开始,而不是直接看迁移日志。


















