CodeIgniter中邮件发送失败时如何实现重试?
在CodeIgniter中实现邮件发送失败自动重试
针对你遇到的「SSL: Handshake timed out」偶发问题,确实可以通过封装重试逻辑来解决——CodeIgniter的邮件类本身没有内置重试机制,但我们可以自己实现一个简单的重试函数来处理这种临时网络波动问题。
实现步骤
首先,在你的控制器(或者封装一个通用工具类)里添加一个带重试逻辑的邮件发送方法:
private function sendEmailWithRetry($emailConfig, $emailData, $maxRetries = 1) { // 初始化邮件类 $this->load->library('email'); $this->email->initialize($emailConfig); // 填充邮件内容 $this->email->from($emailData['from'], $emailData['from_name']); $this->email->to($emailData['to']); $this->email->subject($emailData['subject']); $this->email->message($emailData['message']); // 执行带重试的发送逻辑 $attempts = 0; $sendSuccess = false; do { $attempts++; $sendSuccess = $this->email->send(); if (!$sendSuccess) { // 记录错误日志,方便后续排查 log_message('error', "邮件发送失败(第{$attempts}次尝试): " . $this->email->print_debugger()); // 非最后一次尝试时,等待后重置邮件状态重试 if ($attempts < $maxRetries) { sleep(2); // 等待2秒,避免频繁请求触发服务器限制 $this->email->clear(TRUE); // 清空邮件类的所有状态,确保重试环境干净 } } } while (!$sendSuccess && $attempts < $maxRetries); return $sendSuccess; }
然后修改你的insertar_exportacion方法,调用这个重试发送方法:
public function insertar_exportacion() { $insertstatus = $this->exportaciones_model->nuevoExportacion(); if ($insertstatus) { $data['query'] = $this->exportaciones_model->obtenerDatosInsertar(); // 根据你的实际需求配置SMTP参数 $emailConfig = array( 'protocol' => 'smtp', 'smtp_host' => '你的SMTP服务器地址', 'smtp_port' => 465, 'smtp_user' => '你的邮箱账号', 'smtp_pass' => '你的邮箱密码/授权码', 'smtp_crypto' => 'ssl', 'mailtype' => 'html', 'charset' => 'utf-8', 'wordwrap' => TRUE, 'timeout' => 30 // 延长超时时间,给SSL握手足够的处理时长 ); // 准备邮件内容 $emailData = array( 'from' => '系统邮箱@example.com', 'from_name' => '导出系统通知', 'to' => '接收人邮箱@example.com', 'subject' => '导出任务完成通知', 'message' => '您的导出操作已完成,可登录系统查看详情。' ); // 调用重试方法,最多重试1次(即总共尝试2次) $emailSuccess = $this->sendEmailWithRetry($emailConfig, $emailData, 1); if ($emailSuccess) { echo "导出成功,通知邮件已发送"; } else { echo "导出成功,但邮件发送失败(已完成重试)"; // 这里可以根据需求做后续处理,比如记录到数据库或触发告警 } } else { echo "导出操作失败"; } }
额外注意事项
- 延长超时时间:默认的SMTP超时时间较短,设置
'timeout' => 30能有效降低SSL握手超时的概率。 - 控制重试频率:重试间隔建议设置2-5秒,过短的间隔可能被邮件服务器判定为恶意请求。
- 完善日志记录:通过
log_message记录每次失败的详细信息,后续可以通过日志分析是否存在服务器稳定性或网络问题。 - 重置邮件实例:每次重试前必须调用
$this->email->clear(TRUE),避免旧的邮件数据干扰新的发送请求。
内容的提问来源于stack exchange,提问作者Pahoran Alanis
相关产品推荐
相关产品推荐

