寄送電子郵件與字元編碼設定的示意圖

← INSIGHTS & PERSPECTIVES | 後端開發

PHP 寄送 UTF-8 信件標題亂碼:header 與內文編碼設定完整指南

寄送 UTF-8 中文信件時標題或寄件者變亂碼?本文說明電子郵件標準表頭不允許雙位元文字的原因,並用 mb_encode_mimeheader() 與 base64_encode 的 PHP 範例,解決 mail() 函式寄信亂碼問題。

用 PHP 的 `mail()` 函式寄送 UTF-8 中文信件時,信件標題或寄件者名稱經常變成亂碼。這篇文章說明亂碼的根本原因——電子郵件標準格式中表頭不允許雙位元文字——並提供 `mb_encode_mimeheader()` 與 `base64_encode()` 兩種解法與完整程式碼範例。

為什麼 UTF-8 信件的標題和 header 會變成亂碼?

現在大多數的信件系統都已使用 UTF-8,但之前寄出 UTF-8 的信件時,我常遇到信件標題和 headers 資訊變成亂碼的問題。查了老半天網路才發現,不支援的主要原因在於:

電子郵件標準格式(RFC 822 系列)中,表頭(header)的部分不允許使用雙位元的文字。

也就是說,信件內文本(body)宣告 `charset=utf-8` 後可以正常顯示中文,但標題(Subject)、寄件者名稱(From)這些表頭欄位只能放單位元字串。所以解法是使用 `mb_encode_mimeheader()` 函式,將雙位元文字編碼為單位元字串(MIME encoded-word 格式)。

如何用 mb_encode_mimeheader() 解決標題亂碼?

以下為 headers 的範例:

```php

mb_internal_encoding('UTF-8');

$headers = 'MIME-Version: 1.0' . "\r\n";

$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";

$headers .= 'From: '.mb_encode_mimeheader('標題') .'<[email protected]> ' . "\r\n";

mail($to, mb_encode_mimeheader($title, 'UTF-8'), $content, $headers);

```

重點有三處:

  1. `mb_internal_encoding('UTF-8')` 先指定內部編碼,確保 mb_* 函式正確處理字串。
  2. `Content-type: text/html; charset=utf-8` 讓信件內文以 UTF-8 顯示。
  3. 標題與寄件者名稱都要過 `mb_encode_mimeheader()`,把中文編碼成 MIME 格式。

這樣便可成功解決「郵件標題」或「寄件者」是亂碼的問題。

沒有 mbstring 函式庫時,怎麼用 base64_encode 寄信?

若是電腦沒有安裝 `mb_encode_mimeheader()` 的函式庫(mbstring),則可以使用下面的程式碼來寄信——原理相同,改用 `base64_encode()` 手動組出 `=?UTF-8?B?...?=` 的 MIME encoded-word:

```php

$to =" [email protected] "; //收件者

$subject="=?UTF-8?B?".base64_encode('主旨')."?=";//信件標題,解決亂碼問題

$msg = "smtp發信測試";//信件內容

$from_name="香腸" ; //寄件者名稱

/ 把$from_name進行編碼,解決寄件者名稱亂碼問題 /

$from_name="=?UTF-8?B?".base64_encode($from_name)."?=";

$headers = "From:".$from_name." <[email protected]>"; //寄件者名稱和信箱

if(mail("$to", "$subject", "$msg", "$headers"))

echo "信件已經發送成功。";//寄信成功就會顯示的提示訊息

else

echo "信件發送失敗!";//寄信失敗顯示的錯誤訊息

```

`=?UTF-8?B?....?=` 是 MIME encoded-word 的標準格式:`UTF-8` 是字元集,`B` 表示 Base64 編碼。收件端的郵件軟體看到這個格式就會自動解碼回中文,亂碼問題隨之消失。

延伸閱讀

常見問題

Q為什麼信件內文正常顯示,標題卻是亂碼?

因為電子郵件標準格式中,表頭不允許雙位元文字,只有內文可以透過 `charset=utf-8` 宣告編碼。標題、寄件者名稱屬於表頭,必須先用 `mb_encode_mimeheader()` 或 Base64 編碼成 MIME encoded-word 才能正常顯示。

Qmb_encode_mimeheader() 是什麼?

它是 PHP mbstring 擴充提供的函式,會把 UTF-8 等多位元字串編碼成單位元的 MIME encoded-word 字串(如 `=?UTF-8?B?...?=`),讓中文可以安全地放進信件表頭。使用前先用 `mb_internal_encoding('UTF-8')` 指定內部編碼。

Q沒有安裝 mbstring 時怎麼辦?

可以改用 `base64_encode()` 手動組出 `=?UTF-8?B?` + base64 字串 + `?=` 的格式,套在信件標題與寄件者名稱上,效果與 `mb_encode_mimeheader()` 相同。本文第二段程式碼就是完整範例。

Q信件內文要如何避免亂碼?

在 headers 加上 `MIME-Version: 1.0` 與 `Content-type: text/html; charset=utf-8`,並確保 `$content` 本身是 UTF-8 編碼,內文就會正常顯示中文。

參考資料

  • PHP 官方文件:mb_encode_mimeheader
  • PHP 官方文件:mail() 函式
  • RFC 2047:MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text

最後更新

2026-08-28(原文發布於 2011-02-14,本文保留原始筆記內容並補上 GEO 結構。)

關於作者 {#author}

Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。

首次發布:2011-02-14