ネット上に溢れている情報が、古かったりいろいろで、コピペしたコードをそのままPHPのプログラムに貼って送信すると、メールが文字化けするということがよくあります。

そもそも、ネット上に溢れている間違ったサンプルコードは、mb_send_mail()関数やmb_encode_mimeheader()関数の挙動がよくわかっていないまま掲載している模様です。正しく文字エンコーディングを理解していないまま、「その時動いた」という限定的な状況を記事として掲載しているのが問題です。(その検証が、以下のPHP都市伝説のページでも述べられていました。

結論として、文字化けしたときにチェックすべきポイント:

  • (1)どの文字コードでPHPのソースコードを保存しているか?
  • (2)mbstring拡張ライブラリにどの文字コードを設定しているか?
  • (3)間違ったエンコード処理を行っていないか?(不要な文字コード変換していないか?)

基本的なメール送信のコードは、以下のとおり。以下のソースコードを、正しく、mb_internal_encoding()の設定であるUTF-8で保存することが動作条件です。

<?php
// 言語と文字エンコーディングを正しくセット
mb_language("Japanese");
mb_internal_encoding("UTF-8");
// 宛先情報をエンコード
$to_name = "宛先太郎";
$to_addr = "taro@example.com";
$to_name_enc = mb_encode_mimeheader($to_name,"ISO-2022-JP");
$to = "$to_name_enc<$to_addr>";
// 送信元情報をエンコード
$from_name = "送信元次郎";
$from_addr = "jiro@example.com";
$from_name_enc = mb_encode_mimeheader($from_name, "ISO-2022-JP");
$from = "$from_name_enc<$from_addr>";
// メールヘッダを作成
$header  = "From: $from\n";
$header .= "Reply-To: $from";
// 件名や本文をセット(ここは自動的にエンコードされる)
$subject = "メールのテスト";
$body = " こんにちは、$to_name さん。元気ですか?";
// 日本語メールの送信
$result = mb_send_mail($to, $subject, $body, $header);
if ($result) {
  echo "Success!";
} else {
  echo "Failed...";
}

これで、メールが正しく送信できたなら、受信したメールのソースコードは次のようになるはず。

To: =?ISO-2022-JP?B?GyRCMDhAaEJATzobKEI=?=<taro@example.com>
Subject: =?ISO-2022-JP?B?GyRCJWEhPCVrJE4lRiU5JUgbKEI=?=
From: =?ISO-2022-JP?B?GyRCQXc/Ljg1PCFPOhsoQg==?=<jiro@example.com>
Reply-To: =?ISO-2022-JP?B?GyRCQXc/Ljg1PCFPOhsoQg==?=<jiro@example.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

(ここに、JISコードの本文)

メールのヘッダが、ISO-2022-JPで正しくエンコードされているかどうか、受信したソースコードを見て確認できます。

また、メール送信を行うとき、データベースと連携する機会も多いと思うので、その場合、データベースから取り出した文字列のコードを意識することも重要です。

Comments:
ELFあまり言及されることが少ないですが,mb_encode_mimeheader()は気をつけて使わなければ行の長さを適切に扱うことができません.参考:http://wiki.poyo.jp/read/Writing/kiwameru_php_vol.2/01.mai..というかもと原稿で書いていませんでしたが,最後の引数$indentを用いることで正しい文字数に丸め込めるかもしれません (2011/03/17)
クジラ飛行机ELFさん、フォローのコメントありがとうございます! (2011/03/17)
urakami大変参考になりました。ありがとうございます。 (2014/10/15)
Name: