You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PHP发送长邮件的最佳实践及日文乱码问题咨询

解决PHP mail()发送长日文邮件时的乱码问题

你遇到的每495字符左右出现乱码的情况,本质是RFC 5322对邮件内容的行长度限制导致的:邮件传输时,单段内容不能超过998字节,而UTF-8编码的日文字符每个占3字节,495个字符就接近1500字节,远超限制。邮件服务器自动折行时会截断多字节字符,破坏UTF-8的编码结构,最终出现乱码。结合你的场景,给你两个靠谱的解决方案:

一、手动处理MIME编码(原生mail()函数适配)

如果不想引入第三方库,可以通过手动编码来符合RFC规范,步骤如下:

  1. 先统一编码,确保POST数据是UTF-8
    在接收表单数据的PHP文件开头,添加编码强制设置,避免输入数据编码混乱:

    mb_internal_encoding('UTF-8');
    mb_http_input('UTF-8'); // 强制识别POST数据为UTF-8
    
  2. 对邮件主题和正文进行合规编码
    使用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

火山引擎 最新活动