PHPで送ったメールをOutlookで確認するとヘッダが本文に表示されたり改行が倍になったりする
2014年01月24日 19時53分
サーバ環境が変わったとたんに秘伝のソースプロジェクトから送られたメールをOutlook(報告があったのは2003,2007)で確認すると本文中にメールヘッダが出てきたり、本文中の改行が2倍になったりする症状が発生した。
こんな感じ。
環境の違いはガッツリ変わっててMTAがsendmailからpostfixに変更。
また、phpのバージョンが5.1から5.5になった。
調べてみるとやっぱり同じ症状に悩む人が結構いたらしくすぐ情報が見つかる。
共通して言ってることはqmailやpostfixの場合は改行コードを統一しないとまずいということ。
LFに統一したらすぐ治ったが全くの思い込みでドハマリしたのがヒアドキュメント中の改行コード。
今までコード中の改行コードがそのまま反映されるものと思っていたがどうもPHP_EOLになる挙動をする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// コード中の改行コードは全てCRLF // ヒアドキュメントのみ $message1 = <<<COUT hello, world! COUT; $inner_message = "hello, world!\r\n"; // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 $message2 = <<<COUT {$inner_message} COUT; var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), $message1)); var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), $message2)); var_dump(str_replace(array("\r", "\n"), array("<CR>", "<LF>"), PHP_EOL)); |
Windows(Win7, Apache2.2, PHP5.5)で確認すると改行は全てCRLFで思った通りの改行コードになっている。
1 2 3 |
string(37) "<CR><LF>hello, world!<CR><LF><CR><LF>" // ヒアドキュメントのみ string(37) "<CR><LF>hello, world!<CR><LF><CR><LF>" // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 string(8) "<CR><LF>" // PHP_EOL |
しかし、Linux(CentOS6.5, Apache2.2, PHP5.5)で確認すると変数に入れた\r\nのみCRLFで、ヒアドキュメント中の改行は全てLFになっていた。
1 2 3 |
string(25) "<LF>hello, world!<LF><LF>" // ヒアドキュメントのみ string(29) "<LF>hello, world!<CR><LF><LF>" // ヒアドキュメント中に改行(\r\n)を持つ変数を展開 string(4) "<LF>" // PHP_EOL |
こうなるとMTA側でLFをCRLFに変換した時にCRCRLFという改行コードができてメーラーによってマチマチの挙動になっていたと納得。
後、注意すべき点としてはmb_encode_mimeheaderも長い場合は自動で改行するので引数渡して改行コードを指定し、本文の改行コードと合わせる必要がある。
- PHP: mb_encode_mimeheader
- http://www.php.net/manual/ja/function.mb-encode-mimeheader.php