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

如何解决CodeIgniter中SMTP批量邮件发送失败问题

批量SMTP邮件发送失败:仅部分发送后报错

问题描述

编写了sendMail函数用于批量发送邮件,目标数组含60个邮箱地址,但启动服务后仅成功发送10-15封,随后出现以下错误:

from: 遇到以下SMTP错误:

Unable to send data: QUIT
quit:

遇到以下SMTP错误:

Unable to send email using PHP SMTP. Your server might not be configured to send mail using this method.
User-Agent: CodeIgniter

函数代码

function sendMail($to,$cc="",$subject,$message,$title="",$attach="",$from="")
{
    $CI = & get_instance();
    $CI->load->library("email");

    $CI->email->clear(TRUE);
    $CI->email->set_newline("\r\n");
    if($title==""){
        $title="q Group";
    }

    if($from=="") {
        $from="q@q.com.tr";
    }
    $CI->email->from($from, $title);
    if($cc<>"")
        $CI->email->cc($cc);
    $CI->email->subject($subject);

    $CI->email->message($message);
    if($attach<>"")
    {
        $CI->email->attach($attach);
    }
    $mailList = explode(",",$to);
    $sendMailList = "";
    foreach ($mailList as $key=>$item) {
        if (filter_var($item, FILTER_VALIDATE_EMAIL)) {
            $sendMailList .=$item.",";
        }
        else{
            MailLogModel::setLog($item,$subject,0,"Mail Adresi Hatalı");
            if(count($mailList)==1)
                return ["status"=>false,"message"=>"Mail Adresi Hatalı"];
        }
    }
    $sendMail = substr($sendMailList,0,-1);
    $CI->email->to($sendMail);
    if (!  $CI->email->send()){
        MailLogModel::setLog($sendMail,$subject,0,html_entity_decode(imap_utf8($CI->email->print_debugger('headers','subject'))));
        return ["status"=>false,"message"=>$CI->email->print_debugger(array('headers'))];
    }
    else{
        MailLogModel::setLog($sendMail,$subject,1);
        return ["status"=>true];
    }
}

配置文件

$config['protocol']  = "smtp";
$config['SMTPAuth']    = true;
$config['smtp_host'] = "mail.MYSERVICE.com.tr";
$config['smtp_user'] = "";
$config['smtp_pass'] = "";
$config['smtp_port'] = "25";
$config['charset'] = "utf-8";
$config['mailtype']    = "html";
$config['newline'] = "\r\n";
$config['crlf'] = "\r\n";
$config['smtp_timeout']    = 5;

解决方案

1. 修复SMTP认证配置

配置中SMTPAuth设为true但smtp_user和smtp_pass为空,这会导致认证失败:

  • 如果SMTP服务器需要认证:填写正确的用户名和密码
  • 如果不需要认证:将SMTPAuth改为false

2. 调整SMTP连接策略,避免复用单连接

多数SMTP服务器会限制单连接的发送次数(通常10-15封),超过后会主动断开连接。需每次发送后重新初始化邮件库:

  • 若外部循环调用sendMail,每次调用前销毁并重新加载库:
    unset($CI->email);
    $CI->load->library('email');
    
  • 若函数内部批量发送,改为逐个处理邮箱,每次发送前重置邮件实例:
    // 替换原合并收件人的逻辑,改为逐个发送
    foreach ($mailList as $key=>$item) {
        if (!filter_var($item, FILTER_VALIDATE_EMAIL)) {
            MailLogModel::setLog($item,$subject,0,"Mail Adresi Hatalı");
            continue;
        }
        // 每次发送前重置邮件配置
        $CI->email->clear(TRUE);
        $CI->email->from($from, $title);
        if($cc<>"") $CI->email->cc($cc);
        $CI->email->subject($subject);
        $CI->email->message($message);
        if($attach<>"") $CI->email->attach($attach);
        $CI->email->to($item);
    
        if (!$CI->email->send()){
            MailLogModel::setLog($item,$subject,0,html_entity_decode(imap_utf8($CI->email->print_debugger('headers','subject'))));
        } else {
            MailLogModel::setLog($item,$subject,1);
        }
    }
    

3. 更换SMTP端口与加密方式

端口25常被防火墙或ISP拦截,建议改用标准加密端口:

  • 使用TLS加密(端口587):
    $config['smtp_port'] = 587;
    $config['smtp_crypto'] = 'tls';
    
  • 或使用SSL加密(端口465):
    $config['smtp_port'] = 465;
    $config['smtp_crypto'] = 'ssl';
    

同时延长超时时间,避免网络延迟导致断开:

$config['smtp_timeout'] = 10;

4. 添加发送频率控制

部分服务器会限制短时间内的发送频率,可在逐个发送的循环中添加延迟:

sleep(2); // 每发送一封后暂停2秒,根据服务器要求调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:25:22