Home > PHP > PHPのmail()関数で日本語メールを送信するとSubjectの20文字目から文字化けする

PHPのmail()関数で日本語メールを送信するとSubjectの20文字目から文字化けする

  • 2010-01-12 (火) 0:13
  • PHP
  • 投稿者:hitotsu
PHPのmail()関数に渡すSubjectに漢字をMIMEエンコードしたものを渡すと、長いタイトルの時に20文字目から文字化けすることに気が付いた。
ターゲットはPHP 5.2.1。
問題のメールのSubject(タイトル)を生成する部分
$subject = mb_encode_mimeheader(mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8"),"ISO-2022-JP","B","\r\n");

これだと

「開発者ブログる。投稿者さんからメールテストです」

が20文字目から文字化けして以下のようになる。

「開発者ブログる。投稿者さんからメールテ9%H$G$9」

PHPスクリプトファイルはUTF-8。
mail()関数のバグの可能性もあると思ったが、
そろそろ枯れているはず(と思いたい)なので、調べてみた。
結論を書くと、mail()関数のせいではない。
mail()関数に渡すMIMEエンコードしたSubjectに問題があった。
つまりmb_encode_mimeheader()が原因である。
対処方法は以下のとおり。

次のようにmb_encode_mimeheader()を使う前に、internal_encodingを変更すると
正しくマルチバイト文字をエンコードできるようになった。
$org = mb_internal_encoding();	// 元のエンコーディングを保存
mb_internal_encoding("ISO-2022-JP");// 変換したい文字列のエンコーディングをセット
$subject = mb_encode_mimeheader(mb_convert_encoding($subject, "ISO-2022-JP", "UTF-8"),"ISO-2022-JP","B","\r\n");
mb_internal_encoding($org);// エンコーディングを戻す
問題なくタイトルや長い文字列でもエンコードできるようになった。
以下のブログが参考になった。
どうもありがとう。
PHPのmb_encode_mimeheaderは事前にmb_internal_encodingが必要
[編集履歴]
  • 2010-02-18 修正後のソース中、mb_convert_encoding中のsubjectに$が付いていなかったので付加

Comments (Close):4

rtanaka1ro 11-02-26 (土) 1:06
Gmailなどで問題ないけどBecky!で文字化けして困ってましたが、 この記事の通りにしたらお陰さまで無事解決しました。
植物お世話係 11-02-26 (土) 1:30
rtanaka1ro さん、解決してよかったですね。 お役に立てて何よりでした!
Nobu 13-02-17 (日) 23:25
試行錯誤しても直らず困っていました。 本当に助かりました! ありがとうございます!
hitotsu 13-02-18 (月) 0:20
Nobuさん、直ってよかったですね。 お役に立てて何よりでした!

Trackbacks (Close):1

trackback from 第2.5地区 10-08-26 (木) 17:36
[プログラミング]PHP メールのタイトルが文字化けする メールのタイトルが文字化けする といっても、PCのアドレス宛に送信されたメールのタイトルは問題ない。 PCのアドレスからさらに携帯へ転送していて、携帯で見るとタイトルが文字化…