PHP mail() and charset encoding question, part2 - mbstring
php mail mbstring
在 part1 中提到 mail() 會固定對信件內容進行編碼,而解決之道是改用 PHPMailer, PEAR::Mail 寄送信件。而本文則要繼續探索 mail() 對信件內容編碼之原因。
在一次測試過程中,我很偶然地、不小心地,打錯了 $headers 中 Content-type 的字元集(charset)之值,結果找到 mail() 寄信會造成亂碼的原因。
下例將故意字元集之值故意輸入成 'utf-X' (請將範例程式碼以 UTF-8 編碼格式儲存)。
結果 PHP 顯示了一則警告訊息,如下所示:
Warning: mb_send_mail():
Unsupported charset "utf-X" - will be regarded as ascii in ...
這下我明白了,凶手就是 mb_send_mail()。原來 mail() 實際上已經被 mb_send_mail() 覆寫了,而 mb_send_mail() 會判讀 header 內容對信件內容編碼。這正是造成亂碼的原因。
我直覺想到這與 mbstring extension 有關。只要不載入 mbstring extension 或是在 php.ini 中設定 mbstring.func_overload = 6(not overload mail()),那麼問題便可迎刃而解。我測試後確實可解,取消 mbstring.func_overload 對 mail() 之覆寫動作後, mail() 的行為跟以前一樣,不會對信件內容亂編碼。
但在實務上,有不少人是租用虛擬主機空間運行 PHP 程式。而那些虛擬主機供應商不可能允許用戶自行修改 php.ini 之內容。所以此處的解決方式不適合虛擬主機用戶,他們應採用 part1 的解決方式。
Posted by shirock at
樂多Roodo! │09:13
│
回應(4)
│
引用(0)
│
PHP
引用URL
http://cgi.blog.roodo.com/trackback/2998451

請問一下當我用像下面的程式去跑的時侯為什麼在信件的本文的部份常會莫名的跑出!或亂碼...本文部份是讀入utf8格式的中文字..是那個部份 下錯 了嗎 ??謝 謝
$subj='=?utf-8?B?' . base64_encode("中文測試").'?=';
$to = 'melu@yahoo.com';
$from = '英文';
$mime = md5(uniqid(mt_rand(),TRUE));
$header = "From:=?utf-8?B?".base64_encode($from)."?=\r\n";
$header .= "MIME-Version:1.0\r\n";
$header .= "Content-Type: multipart/alternative;boundary=".$mime."\r\n";
$header .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$msg="";
$msg .= "--".$mime."\r\n";
$msg .= "Content-Type: text/plain; charset=UTF-8\n";
$msg .= "Content-Transfer-Encoding: 8bit\n\n";
$msg .= "--".$mime."\r\n";
$msg .= "Content-Type: text/html; charset=UTF-8\n";
$msg .= "Content-Transfer-Encoding: 8bit\n\n";///////////////////////////
//--------------------------
$msgbody="";
$msgbody.="";
$msgbody.="";
$msgbody.="";
$msgbody.="";
$msgbody.="";
$msgbody.=" ";
$msgbody.=" 中文測試";
$msgbody.=" ";
$msgbody.="";
$msgbody.="";
$data = $msgbody;
$msg .= $data."\r\n";
$msg .= "--".$mime."--\r\n";
mb_internal_encoding("UTF-8");
mb_send_mail($to, $subj, $msg, $header);

只要不載入 mbstring extension 或是在 php.ini 中設定 mbstring.func_overload = 6(not overload mail())
-----------------------------
當我在php.ini下查看。
發現這個本來就沒有載入了
(;mbstring extension =0 )
仍然呈現亂碼。
似乎~並不是出自於這裡的問題
你有試著用 php -m 列出 PHP 編入的 extension 有哪些嗎?如果你的 php 是將 mbstring 直接編譯在一起的話,就會作用。這時不理會 php.ini 中的設定。