Codeigniter 3使用smtp.office365.com发送邮件时内容截断问题
问题分析与解决建议
可能的原因
- CodeIgniter 3邮件类的SMTP换行逻辑与Office365 SMTP不兼容:Office365严格遵循RFC 2822标准,要求邮件每行长度不超过76字符,且换行必须为CRLF(
\r\n)。CI3默认的换行处理或编码逻辑不符合该要求,导致Office365服务器解析时出现错误的截断与=字符残留(这类=是Quoted-Printable编码的异常标记)。 - Quoted-Printable编码处理异常:当邮件正文包含UTF-8字符或长文本时,CI3邮件类的QP编码逻辑存在缺陷,无法生成符合Office365要求的编码格式,最终导致正文乱码截断。
wordwrap配置冲突:开启wordwrap后,CI3的自动换行规则与SMTP传输要求的行长度限制不匹配,触发Office365服务器的错误解析。
排查步骤
- 禁用
wordwrap测试:将配置中$config['wordwrap']设为FALSE,发送测试邮件,确认是否为自动换行导致的问题。 - 查看邮件原始源码:在收件邮箱中查看邮件的原始源码,检查是否存在错误的换行符(如仅用
\n而非\r\n)、异常的QP编码标记。 - 对比正常邮件源码:用其他可正常发送的SMTP服务器发送相同内容,对比两份邮件的编码格式、换行符、行长度,定位差异点。
解决方法
方法1:调整CI邮件类的换行与编码逻辑
修改CodeIgniter核心库system/libraries/Email.php:
- 找到
_smtp_send()方法,将所有单独的\n替换为\r\n,确保SMTP传输使用标准CRLF换行。 - 找到QP编码相关的处理代码(如
_encode_quoted_printable方法),确保每行长度严格控制在76字符以内,且换行使用CRLF。
方法2:添加自定义配置参数
在邮件配置中添加以下参数(若CI3支持),强制使用标准格式:
$config['crlf'] = "\r\n"; // 强制使用CRLF换行 $config['wrapchars'] = 76; // 匹配QP编码的行长度限制
若CI3默认不支持上述配置,可在发送邮件前手动处理正文:
// 替换所有换行为CRLF $message = str_replace("\n", "\r\n", $message); // 手动执行QP编码 $message = quoted_printable_encode($message);
方法3:替换为第三方邮件库
改用PHPMailer(对Office365 SMTP兼容性更强)替代CI原生邮件类:
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; $mail = new PHPMailer(true); try { // SMTP配置 $mail->isSMTP(); $mail->Host = 'smtp.office365.com'; $mail->SMTPAuth = true; $mail->Username = 'noreply@domain.com'; $mail->Password = 'your_password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 收发件人设置 $mail->setFrom('noreply@domain.com', '发件人名称'); $mail->addAddress('收件人邮箱@example.com', '收件人名称'); // 邮件内容 $mail->isHTML(true); $mail->Subject = '测试邮件主题'; $mail->Body = '<p>你的HTML邮件正文内容</p>'; $mail->AltBody = '纯文本备用内容'; $mail->send(); } catch (Exception $e) { echo "邮件发送失败: {$mail->ErrorInfo}"; }
方法4:验证Office365 SMTP要求
- 确保使用STARTTLS加密(端口587),Office365部分环境不支持SSL(端口465)。
- 发件人地址必须与SMTP登录账号完全一致,否则可能被服务器拦截或异常处理。
内容的提问来源于stack exchange,提问作者Esar-ul-haq Qasmi
相关产品推荐
相关产品推荐

