PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった
PHPから送信しているメールで
「件名が途中で切れて、本文の先頭にメールヘッダらしきものが付く」
という不具合が起きた。
この不具合、毎回必ず起きるわけではなく、また発生した場合もすべてのメール受信者のところで起きているわけではなかった(ほぼ同じ内容のメールを複数の人に送信している)。
現象を報告してきた人はOutlook2013を使っているとのことなので、自分のPCにOutlook2007と2013をインストールして同じ件名・本文のメールを受信した見たが、問題なく受信できた。ThunderbirdやGmailでも問題なし。
調査の結果として
「まあサーバ側の処理もよろしくなかったかもしれないけど、Outlookもちょっとおかしいんじゃね?」
という結論に^^;
まず、サーバ側でまずかったのは、改行コードとしてCRLFとLFが混在していたこと。
Subject以外のヘッダは
$content_type = "Content-Type: text/plain; charset=ISO-2022-JP\n";
のようにしている。改行コードはLF。
しかし、Subjectヘッダは
$subject = mb_encode_mimeheader($subject, 'ISO-2022-JP-MS');
としていた。mb_encode_mimeheader() を第3,4引数が省略可で、その場合、第4引数$linefeed のデフォルト値は "\r\n" 。
つまり、Subjectヘッダだけ改行コードがCRLFになっていたと思われる。
これを
$subject = mb_encode_mimeheader($subject, 'ISO-2022-JP-MS', 'B', "\r\n");
としたところ、問題は発生しなくなった。
もう少し詳しく調査をしてみた。
問題発生した環境でメールをファイルに保存してもらい、それをテキストファイルで開いてみると、Subjectヘッダ付近は以下のようになっていた。
Subject: =?iso-2022-jp?B?*******************************************************=?= MIME-Version: 1.0 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 15.0 Thread-Index: AdCXa30bcJOZvjFWQ+GQbisiXjOi/Q== =?ISO-2022-JP?B?***************************=?=
1行目の値をデコードするとメーラーに件名として表示されいる内容(途中でちょん切られた件名)と一致した。
Thred-Indexというヘッダの下に空行があり、その下の行はメーラーで本文の1行目として表示されているものと一致した。
あー、たぶんこういうことだ。
なぜ問題が発生する場合と発生しない場合があるかというと、問題の発生条件が件名の長さによるからだ。
mb_encode_mimeheader() はエンコードした結果が74文字より長いと改行を入れて分割する。これはメールの仕様上問題はない。
件名が短くて分割されない場合、メールの改行コードはすべてLFで問題が発生しない。
しかし、件名が長くてSubjectヘッダが分割されると、mb_encode_mimeheader() の引数$linefeed をデフォルトのままにしていたせいで、その分割のところだけ改行コードがCRLFになる。そしてそのヘッダをOutlookがうまく処理できなくて今回の問題が発生した。
根本的な原因は自分のコーディングにあったのだが、それでも問題が発生したのはOutlookだけだ。それにOutlookでも必ず発生するわけではない。
テキストファイルで開いたメールのヘッダでThread-IndexというヘッダはOutlookが付加する非標準のヘッダだそうだ。
そしてその下に空行が入って、さらに分割されたSubjectヘッダの後半がある。
Outlookでも現象が起きたり起きなかったりするのは、設定とか環境(Exchangeのメール以外のサービスを何か使っているとか)によってこのThread-Indexというヘッダを使う/使わないが変わって、それで使う場合にのみこの現象が発生するんじゃないかと。
実際、現象が発生しなかった自分のOutlook2013で受信したメールを見ると、Thread-Indexはなかった。
という訳で、原因は「Outlookが非標準のヘッダを使っていて、その処理がなんかおかしい」ということで。
#責任回避。
参考ページ:
【php】mail関数の改行コード注意点 at softelメモ
PHP: mb_encode_mimeheader - Manual
メールヘッダ一覧
メールのヘッダフィールド・マニアックス: 非標準 - 鳥さんの落書き帳
« LaravelでHello World とか諸々 | Main | PHPからPDOでPostgreSQLに接続する »
「PHP」カテゴリの記事
- PHPStorm 2018.1.7 に更新(2018.12.09)
- PHPメモ051:includeとrequireの使い分け(2015.06.19)
- CakePHPのインストール(2015.06.14)
- PHPからPDOでPostgreSQLに接続する(2015.06.09)
- PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった(2015.05.31)
The comments to this entry are closed.
TrackBack
Listed below are links to weblogs that reference PHPでメールを送信したら一部のOutlookで受信したメールでヘッダがおかしくなった:
« LaravelでHello World とか諸々 | Main | PHPからPDOでPostgreSQLに接続する »
Comments