PHP发送长邮件的最佳实践及日文乱码问题咨询
解决PHP mail()发送长日文邮件时的乱码问题
你遇到的每495字符左右出现乱码的情况,本质是RFC 5322对邮件内容的行长度限制导致的:邮件传输时,单段内容不能超过998字节,而UTF-8编码的日文字符每个占3字节,495个字符就接近1500字节,远超限制。邮件服务器自动折行时会截断多字节字符,破坏UTF-8的编码结构,最终出现乱码。结合你的场景,给你两个靠谱的解决方案:
一、手动处理MIME编码(原生mail()函数适配)
如果不想引入第三方库,可以通过手动编码来符合RFC规范,步骤如下:
先统一编码,确保POST数据是UTF-8
在接收表单数据的PHP文件开头,添加编码强制设置,避免输入数据编码混乱:mb_internal_encoding('UTF-8'); mb_http_input('UTF-8'); // 强制识别POST数据为UTF-8对邮件主题和正文进行合规编码
使用mb_encode_mimeheader()处理主题(避免主题乱码),用quoted_printable_encode()处理正文,它会自动按RFC要求折行,同时保留UTF-8编码:// 获取表单提交的长日文内容 $formContent = $_POST['contact_content']; // 邮件基础配置 $to = 'your-client@example.com'; $rawSubject = 'お問い合わせ内容の確認'; // 对主题进行Base64编码,适配邮件头规范 $encodedSubject = mb_encode_mimeheader($rawSubject, 'UTF-8', 'B'); // 对正文进行quoted-printable编码,自动处理行长度限制 $encodedBody = quoted_printable_encode($formContent); // 构建符合MIME标准的邮件头 $headers = "From: your-service@example.com\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; $headers .= "Content-Transfer-Encoding: quoted-printable\r\n"; // 发送邮件 $sendResult = mail($to, $encodedSubject, $encodedBody, $headers);
二、使用PHPMailer类库(更推荐)
原生mail()函数需要手动处理很多细节,容易出错,用成熟的邮件类库可以一键解决编码、行长度、SMTP适配等问题。比如PHPMailer:
// 引入PHPMailer类(根据你的安装路径调整) require 'PHPMailer/src/PHPMailer.php'; require 'PHPMailer/src/SMTP.php'; use PHPMailer\PHPMailer\PHPMailer; $mail = new PHPMailer(true); try { // 基础配置 $mail->CharSet = 'UTF-8'; // 直接设置编码为UTF-8 $mail->setFrom('your-service@example.com', 'サポートチーム'); $mail->addAddress('your-client@example.com', 'クライアント様'); // 邮件内容 $mail->Subject = 'お問い合わせ内容の確認'; $mail->Body = $_POST['contact_content']; // 直接传入UTF-8长文本,类库自动处理编码和折行 $mail->isHTML(false); // 如果是HTML邮件,改为true即可 // 发送邮件 $mail->send(); echo 'メール送信が完了しました'; } catch (Exception $e) { echo "メール送信に失敗しました: {$mail->ErrorInfo}"; }
补充说明
为什么刚好在495字符左右出问题?因为UTF-8日文字符(汉字、平假名等)每个占3字节,495×3=1485字节,很多邮件服务器会在接近1500字节时强制折行,这时候如果截断在一个多字节字符的中间,就会破坏UTF-8的编码结构,导致乱码。而quoted-printable编码会把多字节字符转换成=XX的十六进制格式,同时严格按每行76字符(含编码内容)折行,完全符合RFC 5322的要求,从根源避免乱码。
内容的提问来源于stack exchange,提问作者user9203292




