WEB

[PHP]件名も!送信者も!本文も!mail関数で文字化けしないMailHeader設定

Webプログラムを開発していて、メール送信時の文字化けに苦労しませんか?
妥協やごまかしや試行錯誤の末、私なりの文字化けしない設定を見つけました。
もしこれと同じように実装してみて、文字化けするよ!って方がいましたら、是非ご一報ください。
一緒に文字化けしないMailHeader考えましょう!

下記のような条件でメールを送りたい

各種メーラーで受信したときに文字化けしないように

  • 通常のメーラー(outlook, windows live mail, etc.)
  • Webフリーメール(yahooメール、Gmail)
  • それらをスマホで受信した場合(iPhone, Android)

本文はUTF-8、件名はISO-2022-JP

  • 本文はshift-JIS以外の拡張文字も対応したいので、UTF-8
  • しかし件名はUTF-8で文字化けするメーラーがまだ微妙なレベルで存在するのでjisからISO-2022-JP
    ※件名に絵文字とか半角カナとか使うと化ける可能性もあります。

mb_send_mailではなくて、mailで送る

  • mb_send_mail関数は日本語メールを送るのによく利用してきましたが、内部でどのような処理がされているのかよくわからず、サーバーを乗せ換えたら文字化けたなんてこともあるので、mail関数を利用します。

実際のコード

※前提:charaset関係の設定は.htaccessで下記指定しています
php_value default_charset UTF-8
php_value mbstring.language Japanese

//これを指定しないとFromの表示名が化ける 
mb_internal_encoding("utf-8");

//宛先、Fromを設定 
$to = "toaddress@example.com"; 
$fromname = mb_encode_mimeheader("送信者名"); 
$from = "fromaddress@example.com";
 
//headerを設定 
$charset = "UTF-8"; 
$headers['MIME-Version'] = "1.0"; 
$headers['Content-Type'] = "text/plain; charset=".$charset;
$headers['Content-Transfer-Encoding'] = "8bit"; 
$headers['From'] = '"'.$fromname.'"<'.$from.'>"';

//headerを編集 
foreach ($headers as $key => $val) { 
  $arrheader[] = $key . ': ' . $val; 
} 
$strHeader = implode("\n", $arrheader);

//件名を設定(JISに変換したあと、base64エンコードをしてiso-2022-jpを指定する) 
$subject = "=?iso-2022-jp?B?".base64_encode(mb_convert_encoding("メールの件名です","JIS","UTF-8"))."?=";
 
//本文を設定
$body = "これが本文です";
 
//送ります! 
mail( $to, $subject, $body, $strHeader );
reiko suzuki
OLD SKOOLシステムエンジニア。ねこを撫でながら働いています。