首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP mail() 發送 UTF-8 中文郵件主旨亂碼:RFC 2047 編碼標準解決方案

     編輯:PHP 綜合知識

mail() 預設不支援非 ASCII 主旨,直接傳入 UTF-8 中文會導致收件端顯示亂碼。依 RFC 2047 標準,主旨需編碼為 =?charset?encoding?encoded-text?= 格式。

問題現象

mail('to@example.com', '中文主旨', '正文內容', $headers);
// 收件箱顯示:???? 或 亂碼

標準解決方案:Base64 編碼 + RFC 2047 格式

function encode_mime_subject($subject, $charset = 'UTF-8') {
    return '=?' . $charset . '?B?' . base64_encode($subject) . '?=';
}

$subject = encode_mime_subject('測試郵件主旨:包含中文');
$headers  = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
$headers .= "Content-Transfer-Encoding: 8bit\r\n";
$headers .= "From: 寄件者 <from@example.com>\r\n";

mail('to@example.com', $subject, '郵件正文內容', $headers);

完整發送函數封裝

function send_utf8_mail($to, $subject, $body, $fromName, $fromEmail, $isHtml = false) {
    $subject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: " . ($isHtml ? 'text/html' : 'text/plain') . "; charset=UTF-8\r\n";
    $headers .= "Content-Transfer-Encoding: 8bit\r\n";
    $headers .= "From: " . mb_encode_mimeheader($fromName, 'UTF-8') . " <$fromEmail>\r\n";
    $headers .= "Reply-To: $fromEmail\r\n";
    $headers .= "Return-Path: $fromEmail\r\n";
    $headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";

    return mail($to, $subject, $body, $headers);
}

// 使用
send_utf8_mail(
    'user@example.com',
    '歡迎註冊【重要通知】',
    '<h1>你好,歡迎加入!</h1><p>請點擊驗證郵箱...</p>',
    '系統通知',
    'noreply@example.com',
    true // HTML 郵件
);

關鍵點補充

  1. 發件人名稱同樣需編碼:使用 mb_encode_mimeheader() 自動處理 RFC 2047
  2. 郵件正文:HTML 郵件設 Content-Type: text/html; charset=UTF-8,純文本設 text/plain
  3. 編碼聲明一致性:Subject、Headers、Body 全鏈路 UTF-8
  4. 長主旨自動換行:RFC 2047 單行限 76 字節,mb_encode_mimeheader() 會自動分段

進階建議:改用專業郵件庫

mail() 依賴本地 MTA(sendmail/postfix),易進垃圾箱、無發送狀態回調、難處理附件/內嵌圖片。生產環境強烈推薦:

  • PHPMailer:composer require phpmailer/phpmailer,SMTP 直連、支援 OAuth2、DKIM 簽名、異步佇列
  • Symfony Mailer:現代化 API、多傳輸層、Tw整合
  • Laravel Mail:框架整合、Markdown 郵件、本地預覽

PHPMailer 範例

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);
try {
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'user@example.com';
    $mail->Password = 'secret';
    $mail->SMTPSecure = 'tls';
    $mail->Port = 587;

    $mail->setFrom('from@example.com', '系統通知');
    $mail->addAddress('to@example.com');
    $mail->Subject = '中文主旨無需手動編碼';
    $mail->Body    = '<h1>HTML 正文</h1>';
    $mail->CharSet = 'UTF-8';
    $mail->send();
    echo '發送成功';
} catch (Exception $e) {
    echo "發送失敗: {$mail->ErrorInfo}";
}

伺服器層面優化(提高送達率)

  1. 配置 **SPF / DKIM / DMARC** DNS 記錄
  2. 設定 **反向解析 (PTR)** 指向發送域名
  3. 使用**獨立 IP** 或信譽良好的 SMTP 服務商(SendGrid, Mailgun, Amazon SES)
  4. 監控退信率、投訴率,定期清理列表
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved