最常见原因是修改.env后未清缓存,应运行php artisan config:clear或config:cache;重点核对mail_mailer、mail_host、mail_port与mail_encryption匹配(如465→ssl)、mail_username为邮箱、mail_password为授权码而非登录密码。

检查 .env 配置是否生效
最常见的情况是修改了 .env 但没清缓存,Laravel 仍读取旧配置。运行 php artisan config:cache 强制刷新配置缓存(注意:开发时可先用 php artisan config:clear 验证)。
重点核对以下几项是否拼写正确、无空格、无中文引号:
-
MAIL_MAILER=smtp(Laravel 7+ 用MAIL_MAILER,不是MAIL_DRIVER) -
MAIL_HOST值必须与邮件服务商文档一致(如 QQ 是smtp.qq.com,163 是smtp.163.com) -
MAIL_PORT和MAIL_ENCRYPTION必须匹配:465 → ssl,587 → tls,25 → null -
MAIL_USERNAME是邮箱地址,MAIL_PASSWORD是授权码(不是登录密码),且不能含特殊字符未转义
验证 SMTP 认证失败的典型错误
报错 Swift_TransportException(530) "Authentication required" 或 "Failed to authenticate on SMTP server",基本锁定在认证环节。
原因和应对方式:
- QQ/163/网易等邮箱必须开启「POP3/IMAP/SMTP 服务」并生成「授权码」,直接填登录密码必失败
- 阿里云/腾讯云等厂商默认封禁 25 端口出站,即使配置了也连不上;优先改用
465/ssl或587/tls - CentOS 上 SELinux 可能拦截 PHP 进程发信,临时测试可运行
sudo setenforce 0,确认后应配策略而非永久关闭 - 某些 SMTP 服务(如 Mailtrap)要求用户名是完整邮箱,有些只要本地部分(如
user而非user@domain.com),需查服务商文档
确认系统级依赖和网络通路
Laravel 发邮件不是纯 PHP 行为,底层依赖系统网络和 OpenSSL 支持。
在 CentOS 上要检查:
- 是否安装了
php-mbstring、php-xml、php-opcache(缺mbstring会导致编码异常,间接引发认证失败) - 防火墙是否放行出站端口:
sudo firewall-cmd --list-ports确认465/tcp或587/tcp在列表中 - 用命令行直连测试:
telnet smtp.qq.com 465或openssl s_client -connect smtp.qq.com:465 -crlf,看能否建立连接 - PHP 的 OpenSSL 是否加载 CA 证书:
openssl.cafile在php.ini中指向有效路径,否则会报certificate verify failed
从日志里抓真实线索
别只看 Laravel 日志(storage/logs/laravel.log),它常只显示“发送失败”,不暴露底层网络或认证细节。
必须同时查:
- 系统邮件日志:
sudo tail -f /var/log/maillog(CentOS/RHEL)或/var/log/mail.log(Debian/Ubuntu) - 如果用了队列,还要看
supervisor或systemd的服务日志:sudo journalctl -u supervisor -n 50 -f - 加一句调试代码,在发送前 dump 实际使用的配置:
dd(config('mail'));,确认username、password、encryption真实值
真正卡住的地方,往往不在 Laravel 层,而在 PHP 扩展、系统策略或网络策略之间那层薄薄的缝隙里——那里没有错误提示,只有沉默的连接超时或被重置。











