根本原因是Laravel缓存未清除:修改.env后需执行php artisan config:clear和config:cache,队列还需queue:restart;SMTP失败常因邮箱地址、端口加密、授权码三者不匹配;线上不发邮件多因.env缺失、云厂商封端口或SELinux拦截。

修改 .env 邮件配置后没反应
根本原因几乎总是缓存没清。Laravel 启动时会把 .env 读进内存,再生成 bootstrap/cache/config.php;后续请求直接读缓存,完全忽略 .env 文件变动。
必须执行:
-
php artisan config:clear—— 删除缓存文件(最基础) -
php artisan config:cache—— 重新生成缓存(改完.env后必做) - 如果用队列发邮件,还要
php artisan queue:restart(队列 worker 不会自动 reload 配置)
别跳过 config:cache:只清不重生成,Laravel 会 fallback 到默认值(比如 MAIL_DRIVER=smtp 但其他字段全空),导致连接失败却报错模糊。
SMTP 认证失败:Failed to authenticate 或 530 错误
这类报错表面是账号密码错,实际常因三处不一致:
-
MAIL_USERNAME和MAIL_FROM_ADDRESS必须是同一个邮箱(QQ/163/Outlook 等服务商强制校验发信地址与登录账号一致) -
MAIL_PORT和MAIL_ENCRYPTION必须配对:465→ssl,587→tls;混搭必连不上 -
MAIL_PASSWORD必须是「授权码」,不是邮箱登录密码(QQ/163/网易邮箱均需在网页端开启 SMTP 并生成独立授权码)
检查命令:php artisan tinker → config('mail'),确认输出里 username、password、encryption 的值是你刚写的,而不是空或默认值。
线上环境死活不发邮件,本地却正常
线上常见但容易被忽略的三个硬性限制:
-
.env文件没传到服务器(Git 忽略了它,手动 scp 或 rsync 漏传)—— 直接ls -l .env看是否存在 - 云服务器(阿里云/腾讯云)默认封禁 25 端口,且部分厂商也限制 465/587 出站 —— 改用 Mailgun/SendGrid 等第三方服务更省事
- SELinux 或防火墙拦截 SMTP 连接(CentOS 常见):
sudo setenforce 0临时关闭 SELinux 测试;再查firewall-cmd --list-all确认 465/587 是否放行
别依赖 php artisan serve 测试线上行为:它绕过 Web 服务器和系统级限制,结果不可靠。
config/mail.php 里的 from 配置被忽略
config/mail.php 中的 from 部分,实际只作为 fallback 使用。Laravel 优先从 .env 读取 MAIL_FROM_ADDRESS 和 MAIL_FROM_NAME,并强制覆盖 config/mail.php 里的对应字段。
如果你在 config/mail.php 里写了:
['address' => 'hello@example.com', 'name' => 'App']
但在 .env 里没设 MAIL_FROM_ADDRESS,那最终发信地址会是 noreply@localhost(Laravel 默认 fallback)—— 而不是你写的 hello@example.com。
所以:所有发信地址相关配置,必须显式写进 .env,哪怕只是复制一遍;否则 config/mail.php 的修改等于白改。


















