[PHP-users 17006]Re: mb_send_mail()と mb_encode_mimeheader()

Youichi Iwakiri yiwakiri @ st.rim.or.jp
2003年 7月 28日 (月) 17:30:23 JST


いわきりです

Shuji TANAKA wrote in <009501c354be$1489a3f0$0a01a8c0 @ longpro> :
> mb_send_mail()は第三引数に追加のヘッダを渡すことができますが,どうやらここ
>に日本語を渡してもMIMEエンコードしてくれないようです.そのために,
>mb_encode_mimeheader()があってこれでエンコードしてから渡してやるべきなような
>のですが,この関数では,文字列の先頭から,ASCII範囲外の文字が出てくる場所ま
>でを走査し,そこから文字列の最後まで全てをbase64エンコードしてしまうようで
>す.
> 規格としてはこれでいいのかもしれませんが,たとえばFrom:ヘッダとして,

アルファベットをJIS X0201 Romanとみなせば、ISO-2022-JPのBエンコードに
含まれても規格としては間違いでは無かったと思いますが、

>「From: 日本語名称 <youraddress @ your.domain>」
> のような文字列を設定してmb_encode_mimeheader()に渡し,結果がmb_send_mail()
>経由でsendmailに渡ると,sendmailがFrom:ヘッダのMIMEエンコードされた文字列を
>ローカルのメールアドレスと見なして,自動的に文字列の後尾に「@your.domain」の
>ようなドメイン名を設定してしまうということが起こりました.

ヘッダフィールドは、US-ASCIIで記述されることと言うのと、
From:ヘッダに関しては、
  From: [displayname] "<" addr-spec ">"
といったような規定があるので "<" addr-spec ">"の部分をUS-ASCIIで無い
他文字コードとしてエンコードするのは拙いと思います。

> sendmailの設定でこれを回避することができるのかもしれませんが,最初から
>From:ヘッダのメールアドレス部分をエンコードしなければこの問題は起こらないと
>思うので,PHP側で何とかならないかと思い,次のような関数群を作成しました.即
>ち,
(snip)
> などを散発的にやってみた分には成功しております.今のところ,mb_send_mail()
>からはテストしておりませんが,コマンドラインで/usr/sbin/sendmailに直接エン
>コードされた文字列を渡している状態です.ただ,あまりさまざまなテストをやる余
>裕がないというか,どのようにテストをやれば良いのか良く分からない,という状態
>でして,どなたかもしお時間をいただけましたら,ソースコードをみて間違い等を指
>摘する(この処理は重い,とか),ちょっと動かしてみて気が付いたところを指摘す
>る,などしていただけないか,と思いまして投稿させていただきました次第です.
> とにかくきちんと規格を調べてやっているわけではないし,どういう処理をすれば
>PHPでは負担がかかるのか,などの知識も欠けております.
> 了解がいただけるようでしたら,次のメールでソースコードをみていただこうと思
>うのですが,いかがでしょうか?.

で、そのコードはいつ見せてもらえますかね :)

個人的には下記のfilterを噛ませて対処しています。
90年代前半からmime-MLで議論され、こと日本語のメッセージ交換に関しては
非常に信頼性があると当方では考えていますが、delegateの配付パッケージに
入っているmimekitをインストールすると
/usr/local/lib/toMime
/usr/local/lib/enMime
/usr/local/lib/fromMime
/usr/local/lib/deMime
といったコマンドが利用できるようになりますが、ヘッダの
エンコード/デコードを適切に行ってくれます。

<?php
define('CRLF', "\n");

function jis_mail($to, $subject, $body, $ext_header = array(), $conv = 'euc-jp')
 {
    $msg  = mb_convert_encoding("To: " . $to . CRLF, 'jis', $conv);
    $msg .= mb_convert_encoding("Subject: ". $subject . CRLF, 'jis', $conv);
    foreach($ext_header as $eh) {
        $msg .= mb_convert_encoding("$eh" . CRLF, 'jis', $conv);
    }
    $msg .= 'Mime-Version: 1.0'. CRLF;
    $msg .= 'Content-Type: text/plain; charset=ISO-2022-JP' . CRLF;
    $msg .= 'Content-Transfer-Encoding: 7bit' . CRLF;
    $msg .= CRLF;
    $msg .= mb_convert_encoding($body, 'jis', $conv);

    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("file", "/dev/null", "a")
    );
    $process = proc_open("/usr/local/lib/toMime | /usr/sbin/sendmail -t -i", $descriptorspec, $pipes);
    if (is_resource($process)) {
        fwrite($pipes[0], $msg);
        fclose($pipes[0]);
        fclose($pipes[1]);
        proc_close($process);
    }
}

$subject = '日本語のsubject';
$body = '日本語のメッセージ';
$xheader = array(
    'X-From: "長い日本語" <iwa_unreachable @ tktools.jp> (12345678901234567890)',
);

jis_mail('iwa_unreachable @ tktools.jp', $subject, $body, $xheader);

?>

-- 
Youichi Iwakiri



PHP-users メーリングリストの案内