最近のメーラーはUTF-8で受けれるよね、ってことで、メールフォームから自分が受けるメールについてはUTF-8でエンコードして受け取るようにしてみたのだけど、一部理解が足りずに上手くないことになってたのでメモしておきます。

起きた問題

差出人の名前が日本語の場合、一部のメーラーで読むと差出人が落ちる。

問題が起きたメーラー

問題が起きたメーラーは以下の通り。
  • Thunderbird 2.0.24
  • Thunderbird 2.0.24からバージョンアップしたThunderbird 3.0.4

問題が起きなかったメーラー

以下のメーラーでは再現しなかった。
  • Becky 2.54
  • Thunderbird Portable 2.0.24
  • Thunderbird Portable 3.0.4

補足

まさか「同じThunderbirdでも環境によって読めないことがある」とは思わなかったので、問題にしばらく気付かなかった。



ダメなコード

mb_language('uni');
mb_internal_encoding("UTF-8");
//宛先
$mailto = "hoge@huga.com";
//件名
$subject = "こんにちは";
//メール本文
$message = "お元気ですか?";
//送信元
$mailfrom = '差出人 <foo@bar.com>';
$headers = 'From: ' . $mailfrom . "\n";
//送信処理
mb_send_mail($mailto, $subject, $message, $headers);

推測される原因

メールヘッダがMIMEエンコードされていないため、メーラー側でその部分を不正と判断し削除してしまう。差出人が表示されないメーラーではメールソース自体から差出人が落ちていた。

対策

きちんとMIMEエンコードを行うようにする。



修正後のコード

mb_language('uni');
mb_internal_encoding("UTF-8");
//宛先
$mailto = "hoge@huga.com";
//件名
$subject = "こんにちは";
//メール本文
$message = "お元気ですか?";
//送信元
$mailfrom = mb_encode_mimeheader('差出人') . '<foo@bar.com>';
$headers = 'From: ' . $mailfrom . "\n";
//送信処理
mb_send_mail($mailto, $subject, $message, $headers);



エンコード周りは取扱いが面倒なので、これがバッドノウハウじゃない自信はないけれども、
とりあえずきちんと「差出人」が表示されるようになりました。

「mb_encode_mimeheader」かー。



参考

PHP: mb_encode_mimeheader - Manual
mb_encode_mimeheaderの都市伝説を検証する - CPA-LABテクニカル




修正(2010/06/10)mb_encode_mimeheaderの使い方が間違っていました。

修正前

$mailfrom = mb_encode_mimeheader('差出人 <foo@bar.com>');

修正後

$mailfrom = mb_encode_mimeheader('差出人') . '<foo@bar.com>';

修正前のコードだとメールを受け取ったときのFrom行が、

差出人<foo@bar.com>@bar.com

となってしまいます。変換が必要なところだけ「mb_encode_mimeheader」を使うのが吉。
よく読んだらマニュアルの例もまんまそうなってました。あわわ。凡ミスでした。

PHP: mb_encode_mimeheader - Manual