You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPMailer提示发信成功未收到 报SMTP连接被拒绝(111)问题咨询

问题概述
  • 初始排查时Web服务器PHP错误日志无相关错误记录
  • 更换多个已验证可用的SMTP服务提供商后,邮件发送失败的故障仍未解决
  • 后续捕获到明确报错信息:

2022-07-07 01:16:57 SMTP ERROR: Failed to connect to server: Connection refused (111)
SMTP connect() failed.


涉及代码

前端联系表单代码

<form action="/mailfunction.php" method="post" id="contact-form">
      <div class="nameInput">
      <input id="boxes" type="text" id="fname" name="name" value="" class="formFormL" placeholder="Name" maxlength="50"></input>
      </div>
      <div class="emailInput">
      <input id="boxes" type="text" id="lname" name="email" value="" class="formFormR" placeholder="Email" maxlength="50"></input>
      </div>

      <div class="messageInput">
      <textarea id="boxes" id="fname" name="message" value="" class="formFormM" placeholder="Message" maxlength="1000"></textarea>
      </div>
      <div style="padding: 5px;">
      <button type="submit" value="Send" class="up" name="submit">Send</button>
      </div>
    </form>

邮件入口文件mailfunction.php代码

<?php 
require '[REDACTED]/mailer.php';

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];

mails($name, $email, $message);

?>

核心邮件发送函数代码

<?php
// 导入PHPMailer相关类,必须放在脚本顶部,不能写在函数内部
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// 加载Composer自动加载文件
require 'vendor/autoload.php';

// 全局实例化PHPMailer属于冗余代码
$mail = new PHPMailer(true);

function mails($name, $email, $message) {

    if(isset($_POST['submit'])){
        // 已经通过传参拿到了表单值,此处重复从$_POST读取属于冗余逻辑
        $name = $_POST['name'];
        $email = $_POST['email'];
        $message = $_POST['message'];

        try{
            $mail = new \PHPMailer\PHPMailer\PHPMailer();
            $mail->isSMTP();
            $mail->Host = 'smtp.gmail.com';
            $mail->SMTPAuth   = true; 
            $mail->Username   = '[REDACTED]'; 
            $mail->Password   = '[REDACTED]'; 
            $mail->SMTPSecure = 'SSL'; 
            $mail->Port       = 465;  

            $mail->setFrom('[REDACTED]');
            $mail->addAddress('[REDACTED]');

            $mail->isHTML(true);                                  
            $mail->Subject = 'Message Received (Contact Page)';
            // 单引号包裹的字符串不会解析变量,最终邮件会直接输出$name/$email/$message字面量
            $mail->Body    = '<h3>Name : $name <br>Email: $email <br>Message : $message</h3>';
            $mail->send();
            echo 'Message has been sent';
            } catch (Exception $e) {
                echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
            }
    }
}

?>

故障原因

Connection refused (111)是TCP连接被目标节点或中间链路直接拒绝的典型报错,和SMTP账号密码、PHPMailer基础逻辑无关,核心诱因按概率排序:

  • 云服务商/机房默认封禁SMTP出站端口:绝大多数公有云厂商默认拦截25、465、587等SMTP常用端口的出站流量,防止服务器被用于发送垃圾邮件,这也是更换多个SMTP服务商仍故障的最常见原因
  • 服务器本地防火墙(iptables、firewalld、CSF等)配置了出站拦截规则,禁止Web进程访问外部SMTP端口
  • 代码层面存在次要配置错误:SMTPSecure参数传入大写SSL不符合PHPMailer的参数要求,该参数仅接受小写ssl/tls或类常量,不过该问题通常会触发加密协商失败报错,不会直接导致连接被拒

代码中还存在3个不影响连接但会导致功能异常的问题:

  • 单引号包裹的邮件正文不会解析PHP变量,用户提交的姓名、邮箱、留言内容不会被正常展示
  • 全局范围重复实例化PHPMailer对象、函数内部重复读取$_POST参数,属于无意义冗余代码
  • 前端HTML存在多个重复id属性,不符合HTML规范,可能引发前端交互异常

修复步骤
  1. 先验证端口连通性:在服务器命令行执行telnet smtp.gmail.com 465和telnet smtp.gmail.com 587,如果直接提示连接失败,优先联系服务器运营商申请解封SMTP出站端口,或直接使用服务商提供的官方邮件推送服务(无需走公网SMTP端口)
  2. 修正PHPMailer加密配置:将$mail->SMTPSecure = 'SSL';替换为$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;(适配465端口);如果使用587端口则替换为$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;,不要手动写字符串避免大小写或取值错误
  3. 修复邮件正文变量解析问题:将正文代码改为双引号包裹,即$mail->Body = "<h3>Name : {$name} <br>Email: {$email} <br>Message : {$message}</h3>";
  4. 清理冗余代码:删除全局范围的$mail = new PHPMailer(true);实例化语句,移除函数内部重复读取$_POST的逻辑,将isset($_POST['submit'])判断移到mailfunction.php入口处,避免无参数访问时空白响应
  5. 清理前端HTML中重复的id属性,保证每个元素id唯一
  6. 端口解封后仍连接失败的,检查服务器本地防火墙规则,放行对应SMTP端口的出站TCP连接

内容的提问来源于stack exchange,提问作者throwaway2908457

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:57:14