ログ日記

作業ログと日記とメモ

mb_send_mail()でそこそこまともなメールを送る

PHPバージョンが変わるとハマったのでメモ。
参考は

超・極める! PHP

超・極める! PHP

これの上鍵さんの記事。


まずMessage-IdとDateフィールド。
これはqmailsendmailラッパを使った場合は勝手に付けられる。
PHPスクリプトを自分の分かる範囲のみで使うなら、サーバが設定してくれるものは全部任せた方がいいと思うのでqmailに任せる。
Envelope-Fromは第五引数に -fmail@address 形式で指定する。
雑誌はEnvelop-Fromとなってるけどeが抜けてる?


改行コードも正しいものに・・って何かややこしい。

第4引数の追加ヘッダと本文で使用する改行文字は、\nでなければならない。


マニュアルにはCRLFとある。

additional_headers(オプション)
メールヘッダの最後に挿入される文字列。
通常、これは追加のヘッダ(From、Cc、Bcc)のために用いられます。 複数のヘッダを追加する場合は CRLF(\r\n)で区切ります。

http://php.net/function.mail

# なんかマニュアルのエラーを発見した・・まぁいいや。

mail()とmb_send_mail()のマニュアル記述が違う・・・わからん。mb_send_mail()のマニュアルがちゃんとメンテされているなら\nが正しそう。

# ていうかこれ書いてて気付いた。直そう。
# qmailも内部の改行コードの扱いが色々あるっぽいし・・どっちかに統一できないもんかねぇ。



で、あとは忘れずに mbstring.language と mbstring.internal_encoding を設定。
ヘッダに

なまえ <メールアドレス>

形式を設定したいなら

<?php
function setMailHeader($type, $mail, $title){
    if (!Validator::isMail($mail))
        return false;

    if ($title)
        $mail = mb_encoding_mimeheader($title) . "<$mail>";

    $this->headers[$type] = "$type: $mail";
    return true;
}
// 送る前に
// $headers = implode("\r\n", $this->headers); する

こういうものを用意。



で、ここまでの設定で今まで送れたんだけどいつの間にか改行がバグるようになってた。
マニュアルには

注意: PHP 5.0.0 以降では、Content-Type および Content-Transfer-Encoding ヘッダの内容が 再定義可能となりました。PHP 4 では、常に mb_language() で定義された値が用いられていました。

http://php.net/mb-send-mail


こう書いてあるだけ。
届いたメールのヘッダを見たら、UTF-8のまま送られてきてるよ。
ちゃんとmb_lanbuage()はJapaneseにしてるハズなのにな。

# 特定のバージョンでUTF-8のときに起こる現象?わからん。



・・ということで自前でContent-TypeとContent-Transfer-Encodingを指定してやる。

Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

これで普通の日本語メールは送れるようになった。



# 後で色々書き足したり修正したりしてると、曖昧な記述になった。環境や設定によって左右されすぎだのぅ。



自分で作ってるクラスの一番の利点はビュー(というかHTML_Template_Flexy用アクションテンプレート)との連動なんだけど、まぁ最近のフレームワークだとそういうの普通にあるよね、きっと。