laravel 9 正确发送邮件需三步:设 mail_mailer=smtp、端口与加密方式严格匹配(如587配tls)、改.env后执行 php artisan config:clear 并查日志。

要让 Laravel 9 正确通过 SMTP 发送邮件,关键不是填一堆参数,而是确保驱动启用、协议匹配、缓存刷新这三步全部到位。Laravel 9+ 已废弃 MAIL_DRIVER,只认 MAIL_MAILER,漏掉这个就根本不会走 SMTP 流程。
必须设置 MAIL_MAILER=smtp
这是硬性前提,其他所有 SMTP 参数(HOST、PORT、USERNAME 等)都依赖它生效。如果没设或设成了 log、array、sync,邮件会静默写入日志或直接丢弃,完全不尝试连接 SMTP 服务器。
- 检查
.env文件,确认有这一行:MAIL_MAILER=smtp - 旧项目升级后容易残留
MAIL_DRIVER=smtp,需删除并替换为MAIL_MAILER - 开发时临时切到 log 驱动调试没问题,但上线前务必核对此项
端口与加密方式必须严格对应
Laravel 的 MAIL_ENCRYPTION 不是“可选开关”,它直接决定底层握手协议。配错就会卡在 Connection could not be established,和账号密码无关。
-
MAIL_PORT=587→ 必须配MAIL_ENCRYPTION=tls(Gmail、Outlook、腾讯企业邮箱、SendGrid 默认用此组合) -
MAIL_PORT=465→ 必须配MAIL_ENCRYPTION=ssl(注意不是tls) -
MAIL_PORT=25或本地测试(如 MailHog)→ 可设MAIL_ENCRYPTION=null,但生产环境禁用 - 阿里云邮件推送、Mailgun HTTP API 不走 SMTP,别混用配置
账号凭证与服务商要求要对得上
很多“认证失败”其实不是密码输错了,而是没满足服务商的强制安全策略。
- Gmail:必须开启两步验证,并在 Google 账户里生成「应用专用密码」(16 位字母数字),填进
MAIL_PASSWORD;不能用登录密码 - QQ 邮箱:开启 SMTP 服务后,授权码就是
MAIL_PASSWORD,不是 QQ 密码 - 企业邮箱或自建 Postfix:确认服务器允许外部连接,防火墙放行对应端口(587/465)
- Mailgun 不是 SMTP 服务,要用
MAIL_MAILER=mailgun+MAILGUN_DOMAIN+MAILGUN_SECRET,删掉所有 SMTP 相关字段
发不出邮件?先看日志再清缓存
改完 .env 后不运行命令,Laravel 仍读取缓存里的旧配置,这是最常被忽略的操作。
- 执行
php artisan config:clear强制重载环境变量 - 查看
storage/logs/laravel.log,搜索Swift_TransportException或535 Authentication failed等关键词 - 用
php artisan tinker检查实际加载值:env('MAIL_MAILER')和config('mail.mailer')应返回smtp - 测试发送可用
Mail::raw('test', function ($m) { $m->to('x@example.com')->subject('test'); });











