
SMTP配置写在哪个文件里才生效
ThinkPHP 6 的邮件发送配置不走 .env 文件默认支持,必须显式写进 config/mail.php。如果你只改了 .env 里的 MAIL_HOST 等变量,但没在 mail.php 中用 env() 读取,那全无效。
正确做法是:打开 config/mail.php,确保 ‘host’、’username’、’password’ 等字段直接或间接取自环境变量:
return [ ‘default’ => ‘smtp’, ‘mailers’ => [ ‘smtp’ => [ ‘transport’ => ‘smtp’, ‘host’ => env(‘MAIL_HOST’, ‘smtp.qq.com’), ‘port’ => env(‘MAIL_PORT’, 587), ‘username’ => env(‘MAIL_USERNAME’, ”), ‘password’ => env(‘MAIL_PASSWORD’, ”), ‘encryption’ => env(‘MAIL_ENCRYPTION’, ‘tls’), ‘from’ => [ ‘address’ => env(‘MAIL_FROM_ADDRESS’, ‘test@example.com’), ‘name’ => env(‘MAIL_FROM_NAME’, ‘Test’), ], ], ],];ThinkPHP 6.1+ 使用的是 symfony/mailer 底层,不认旧版 thinkphp/think-mail 的配置方式MAIL_ENCRYPTION 填 ssl 时端口通常是 465,填 tls 时对应 587,混用会卡在连接阶段,错误信息类似 Connection could not be established with host smtp.qq.comQQ 邮箱、163 邮箱等要求开启 SMTP 并生成「授权码」,不是登录密码;授权码要填进 MAIL_PASSWORD,不是账号密码
发信失败时先看哪几个关键报错
常见失败不是代码写错,而是网络或认证环节断在底层。别急着改逻辑,先盯住异常堆栈最顶上那一行:
Expected response code 250 but got code "535" → 认证失败,大概率 MAIL_USERNAME 或 MAIL_PASSWORD 错,或没开 SMTP 授权Connection timed out → DNS 解析失败或防火墙拦截,可试 telnet smtp.qq.com 587 看通不通Failed to authenticate on SMTP server → 和第一个类似,但有时是加密方式不匹配,比如 QQ 邮箱强制 ssl + 465,你配了 tls + 587Unable to connect with TLS → OpenSSL 扩展未启用,或 PHP 版本太低(symfony/mailer 要求 PHP >= 8.0)
测试配置是否生效的最小验证代码
别用业务逻辑测邮件,写个独立脚本直连发信流程:
立即学习“PHP免费学习笔记(深入)”;
<?phprequire __DIR__ . ‘/vendor/autoload.php’;$app = new \think\App();$mailer = $app->mailer->getMailer();try { $message = (new \Symfony\Component\Mime\Email()) ->to(‘your@email.com’) ->subject(‘TP6 SMTP test’) ->text(‘This is a test.’); $mailer->send($message); echo "OK\n";} catch (\Exception $e) { echo "ERROR: " . $e->getMessage() . "\n";}运行前确认 config/mail.php 已加载(可通过 var_dump(config(‘mail’)) 检查值是否正确)如果提示 Class ‘think\App’ not found,说明没走框架启动流程,此时应改用 new \Symfony\Component\Mailer\Mailer(…) 手动构造,绕过 ThinkPHP 容器测试时关掉队列异步发送,确保是同步执行,避免日志里看不到真实错误
多环境 SMTP 切换容易漏掉的点
开发用本地 MailHog,生产用腾讯企业邮箱,测试用 163 —— 这种场景下光靠 .env 不够,还得检查配置加载顺序:
config/mail.php 是硬编码入口,所有环境都走它;不要在其中写 if (App::isProduction()) { … },会破坏配置缓存机制真正该做环境区分的地方是 .env 文件本身:.env.production、.env.testing,再配合 php think optimize:config 生成对应缓存线上部署后记得清空 runtime/config/ 目录,否则旧配置缓存还在,改了 .env 也无效某些云服务器(如阿里云 ECS)默认屏蔽 25/465/587 端口,需提工单解封,这不是代码问题,但最容易被当成“配置不对”反复折腾
SMTP 配置真正卡住人的,从来不是语法,而是授权、端口、加密方式、网络策略这四层嵌套验证。每层都得单独确认,不能假设上一层过了,下一层就自动 OK。

评论(0)