mail() 預設不支援非 ASCII 主旨,直接傳入 UTF-8 中文會導致收件端顯示亂碼。依 RFC 2047 標準,主旨需編碼為 =?charset?encoding?encoded-text?= 格式。
mail('to@example.com', '中文主旨', '正文內容', $headers);
// 收件箱顯示:???? 或 亂碼
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 郵件
);
mb_encode_mimeheader() 自動處理 RFC 2047Content-Type: text/html; charset=UTF-8,純文本設 text/plainmb_encode_mimeheader() 會自動分段mail() 依賴本地 MTA(sendmail/postfix),易進垃圾箱、無發送狀態回調、難處理附件/內嵌圖片。生產環境強烈推薦:
composer require phpmailer/phpmailer,SMTP 直連、支援 OAuth2、DKIM 簽名、異步佇列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}";
}