laravel邮件配置失败主因是环境变量未生效、驱动非smtp或本地smtp被拦截;需设mail_mailer=smtp、用应用专用密码、匹配端口与加密方式,并用tinker测试,禁用队列调试时用sendnow,本地推荐mailtrap或mailhog。

Laravel 自带的 Mail 组件能直接对接 SMTP 发送邮件,但多数人卡在配置环节——不是发不出去,而是环境变量没生效、驱动没切对、或本地开发时被服务商拦截。
确认 Laravel 使用的是 smtp 驱动而非 log 或 array
默认开发环境下 MAIL_MAILER 可能是 log,它只写日志不真发。检查 .env 文件:
MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=your@gmail.com MAIL_PASSWORD=your_app_password MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=your@gmail.com MAIL_FROM_NAME="MyApp"
注意:MAIL_PASSWORD 不能填邮箱登录密码(Gmail/Outlook 等已禁用),必须用「应用专用密码」或开启 SMTP 授权的 API 密钥;MAIL_ENCRYPTION 要和 MAIL_PORT 匹配(587 → tls,465 → ssl)。
测试配置是否生效:用 php artisan tinker 手动触发发送
别急着跑注册流程,先在命令行验证基础通路:
php artisan tinker
>> use Illuminate\Support\Facades\Mail;
>> Mail::raw('Test from Laravel', function ($message) {
$message->to('test@example.com')->subject('SMTP Test');
});
如果报错 Connection could not be established with host smtp.gmail.com,大概率是防火墙、PHP 的 openssl 扩展未启用,或 DNS 解析失败;若报 Expected response code 250 but got code "535",说明认证失败——重核 MAIL_USERNAME 和 MAIL_PASSWORD,尤其注意 Gmail 必须开两步验证 + 应用专用密码。
发激活邮件时,避免 queue 导致「看似没发送」
很多教程直接用 Mail::to(...)->send(new VerifyEmail()),但如果队列没启动(php artisan queue:work 没运行),邮件会卡在数据库或 Redis 里不动。临时调试建议:
- 发信前加
dd(config('mail'))确认当前加载的配置是.env里的,不是缓存旧值(改完.env后记得php artisan config:clear) - 强制同步发送:在 Mailable 类中加
public function shouldSendNow() { return true; },或调用时用Mail::to(...)->sendNow(new VerifyEmail()) - 不要依赖
QUEUE_CONNECTION=sync来“假装异步”,它只是同步执行队列任务,仍走队列逻辑,不如直接sendNow
本地开发用 Mailtrap 或 MailHog 更可靠
Gmail/163 等生产 SMTP 在本地常因 IP 信誉低被拒收,且无法验证用户点击链接是否有效。推荐:
-
Mailtrap:注册后拿到MAIL_HOST、MAIL_PORT、MAIL_USERNAME、MAIL_PASSWORD,替换到.env即可,所有邮件进 Web 控制台,支持点击链接跳转 -
MailHog:Docker 一键起:docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog,然后设MAIL_HOST=localhost、MAIL_PORT=1025,无认证,适合离线调试
真正上线前再切回生产 SMTP,别让激活链接拼错域名(APP_URL 必须带 https://,否则生成的 URL 是 http://,现代浏览器可能拦截)。











