平成30/ 2018-10-21 05:31
PHP/mail()

___ 本文は1行1000バイト超えると文字化ける。
なので、1000バイトごと(500文字ごと)に改行いれる必要ある。
これは、Postfix側ではできなかった。
設定でそれらしいのあるが、それが2バイト文字の部分に改行とスペースをいれることが問題だから。


//____ メール送信できないときは sendmail or postfix などのメーラの起動有無を確認する。



//___ シンプルにISO-2022.JPで以下でいい。
$to        = $EM;
$from      = $FROM;
$from_name = "";
$bcc       = $BCC;
$subj      = "";
$body      = "";

$header = array();
$header[] = "Content-Type: text/plain;charset=iso-2022-jp";
if(
$from_name
){
    $header[] = "From:" . mb_encode_mimeheader(mb_convert_encoding($from_name, "ISO-2022-JP", "utf8"), "ISO-2022-JP") ."<{$from}>";
} else{
    $header[] = "From:{$from}";
}
$header[] = "Bcc:{$bcc}";
$header   = implode("\n", $header);
$subj     = mb_convert_encoding($subj, "ISO-2022-JP", "utf8");

mb_internal_encoding("ISO-2022-JP");
// これしないと件名が2行になる場合に文字化ける

$subj     = mb_encode_mimeheader($subj, "ISO-2022-JP");
mb_internal_encoding("utf8");


// 1行1000Byte超えると文字化けるのでその対応
$body = preg_replace("/\r\n/u", "\n", $body);
$body = preg_replace("/\r/u",   "\n", $body);
$body = preg_split("/\n/u", $body);
$tmp = array();
foreach($body as $val){
    //echo mb_strlen($val, "utf8"). "\n";
    if(
    mb_strlen($val, "utf8") > 490 // 500にすると文字化けたので余裕もたす
    ){
        $max = mb_strlen($val, "utf8") / 490;
        if(
        $max > floor($max)
        ){
            $max = floor($max)+1;
        }
        $tmp2 = array();
        for($i=0;$i<$max;$i++){
            $tmp2[] = mb_substr($val, ($i*490), 490, "utf8");
        }
        //print_r($tmp2);
        $val = implode("\n", $tmp2);
    }
    $tmp[] = $val;
}
//print_r($tmp);
$body = implode("\n", $tmp);
//echo $body;
$body     = mb_convert_encoding($body, "ISO-2022-JP", "utf8");

if(
//mail($to, $subj, $body, $header, "-f {$from}")
mail($to, $subj, $body, $header) // -f を使ったReturn-Pathの設定はクライアントのセキュリティに引っかかる可能性あるので慎重に
){
}



//____ 関数
function sendmail($em){
    $field = array(
    "to",
    "from",
    "from_name",
    "bcc",
    "subj",
    "body",
    );
    foreach($field as $key){
        if(
        isset($em[$key])
        ){
            ${$key} = $em[$key];
            continue;
        }
        ${$key} = "";
    }
}



//____ うんちく。
define("EM_TO",   "xxx@xxx.com");
define("EM_FROM", "xxx@xxx.com");
define("EM_BCC",  "xxx@xxx.com");

$to     = $dt["em"];
$from   = EM_FROM;
$bcc    = EM_BCC;

$subj = "入力頂きまして有難うございます。";

$body = "このメールは、エントリー登録をいただきますと自動的に送信されます。
このメールに心当たりのない場合や、ご不明な点がございましたら、
までご連絡ください。

今後ともよろしくお願いいたします。
";


$header = array();
#### utf8 の場合
$header[] = "Content-Type: text/plain;charset=UTF-8";
$header[] = "From: {$from}";
// $header[] ="From: " .mb_encode_mimeheader("テスト太郎") ."<test@example.com>";
$header[] = "Bcc: {$bcc}";
$header = implode("\n", $header);
//これしないと件名が74バイトくらいでmb_encode_mineheaderで自動改行されたときに文字化ける。
$subj = mb_encode_mimeheader($subj, "utf8", "B", "\n");
####



// iso-2022-jp の場合
$header = array();
$header[] = "Content-Type: text/plain;charset=iso-2022-jp";

$header[] = "From: " . mb_encode_mimeheader(mb_convert_encoding("いつもお世話になっております", "ISO-2022-JP", "utf8"), "ISO-2022-JP") ."<{$from}>";
//↑utf8=>iso-2022-jpに文字コード変換すると2行目が文字化ける( 74文字で自動改行される )。きっと、mb_encode_mimeheader側で文字コード変換してくれる為だと思う。
// その場合は内部文字円コーディングの設定をする
// mb_internal_encoding("ISO-2022-JP");
// $header[] = "From: " . mb_encode_mimeheader(mb_convert_encoding("いつもお世話になっております", "ISO-2022-JP", "utf8"), "ISO-2022-JP") ."<{$from}>";
// mb_internal_encoding("utf8");

$header[] = "Bcc: {$bcc}";
$header = implode("\n", $header);
$subj = mb_convert_encoding($subj, "ISO-2022-JP", "utf8");


$subj = mb_encode_mimeheader($subj, "ISO-2022-JP");
// 上記と同じく、文字化けるケースがある。その場合は内部エンコーディングの設定をする。
// 以下の感じ。
// mb_internal_encoding("ISO-2022-JP");
// $subj = mb_encode_mimeheader($subj, "ISO-2022-JP");
// mb_internal_encoding("utf8");


$body = mb_convert_encoding($body, "ISO-2022-JP", "utf8");
// "jis"のほうが半角カナに対応しているのでいいらしい。でもヘッダーに文字コード記述してるのならばJISはまずそうだし。


// 僕の経験では、UTF8でなく、iso-2022-jpにしてもらいたい( 古いメーラで文字化ける為 )という要望が多い。


#### メール送信
if(
mail($to, $subj, $body, $header)
//mail($to, $subj, $body, $header, "-f {$from}")
){
}
// "-f {$from}" で「Return-Path」の設定できるが、
以下のエラーが出力される場合があるので慎重に利用した方がいい。
X-Authentication-Warning
上記のエラーでるとスパムメール扱いされて、携帯等でで受信できなくなってしまう。

以上。

( Thanks. )
mb_convert_encoding 関数の ISO-2022-JP と JIS の違い
http://webcache.googleusercontent.com/search?q=cache:u9NWZlUGx_AJ:www.revulo.com/blog/20100602.html+&cd=2&hl=ja&ct=clnk&gl=jp

mb_encode_mimeheader()の使い方
http://blog.cheki.net/archives/1125


メール送信