php5: 2007年9月アーカイブ
phpのmbstring.detect_order は、左から順番に判定をしていくようだ。
私の設定は、
mbstring.detect_order = eucJP-win,UTF-8,SJIS-win,jis
としていて、経験上、これが一番誤判定がでない。(と思う)。
以前は、
mbstring.detect_order = UTF-8,SJIS-win,jis,eucJP-win
とやっていて、eucのはずなのにSJISと判定されたり、UTFと判定されたりした。
(参考)
/halt/Snapshot - mb_detect_orderのautoがぬるい件
【環境メモ】
-----------------------------------------------------------
OS:Windows XP SP2
sever:Apache 1.3.37
php:php 5.2.4
pear 1.6.1:Mail 1.1.14,Mail_Mime 1.5.2,DB 1.7.13,XML_RPC 1.5.1
------------------------------------------------------------
php5.2.4からfatalエラーの時にhttp 500エラーを返すようになった。
Changed error handler to send HTTP 500 instead of blank page on PHP errors.だそうで。
なるほど仕様としてはアリなんだろうけど、デバック時には、普通にエラーの表示をして欲しい。
画面で出すのは研究中。誰か教えて欲しい。
とりあえず、php.iniにてエラーログを出す設定にしておく
log_errors = On
error_log = c:\php5\log\errorlog.txt
【環境メモ】
-----------------------------------------------------------
OS:Windows XP SP2
sever:Apache 1.3.37
php:php 5.2.4
pear 1.6.1:Mail 1.1.14,Mail_Mime 1.5.2,DB 1.7.13,XML_RPC 1.5.1
------------------------------------------------------------
Pear でのMailの送り方は、内部関数mail使用,sendemail(orラッパー)使用,smtp使用と3種類ある(参考:phpでメール送信[Pear::Mail])わけだが、sendmailで、こちらのPEAR::Mailを使ってメールを送信してみようの例でやってみたら下記症状がでた。
----------------------------------------------------
fromのアドレスにメールアドレス以外の文字(例えば名前)をいれるとき、Validation failed というエラーが出た。
---------------------------------------------------
なんじゃらほい。
Validation とは英和辞書によると「~の正当性を立証する」だと?
Pearのソースを眺める。あった。RFC822.phpに、_validatePhrase関数なるものが。
ああ、ここでRFC822に正当に対応(準拠)しているかどうか、というのを調べるのね。
Mailクラスには、function prepareHeadersという関数があるようだ。この関数は、配列に収まっているヘッダー情報をテキストの形に整形する関数。この関数は、fromヘッダを特別扱いしている。ユーザー指定のfromヘッダから、senderを抜き出して、 sendmail (他コマンド) -f(formアドレス)とやるよう。
さらに_validatePhraseにてfromヘッダのデータ(mailbox)をに対するRFC822準拠性チェックを行うのだが、ここで、当該ラインには、英数文字(atom)しか流さないように、チェックが行われており、当然にひらがなはひっかっかってエラーとなる。
つまりは、<メールアドレス>やダブルクオーテーションで囲まれた部分以外は、アルファベットでないとエラーを流す仕組み。
参考:http://www.mew.org/Newsletters/2.html
ああ、ダブルクオーテーション。。
アルファベットなら、ダブルクオーテーションなしで、通る。
日本語なら、ダブルクオーテーションがないとエラー。
つまり、先にmimeエンコード(&base64)しとけってことだ。
というわけで
$header['From'] = "ほげほげ<hoge@hoge.com>";
を
$header['From'] = "\"ほげほげ\"<hoge@hoge.com>";
と直して一件落着。。。ではない。
インターネットのお約束ではダブルクオーテーションの中といえども7bitで流さなくてはならない。これはsendmailラッパーが好意でmimeエンコードしてくれているだけで、こちらとしてはお行儀がよくない。
最初からRFCにきちんと準拠するには、sendmailに渡す前に、mimeエンコードしておかなくてはならない。
というわけで
$a="ほげほげ";
$def_encoding=mb_internal_encoding();
mb_internal_encoding(mb_detect_encoding($a));
$header['From'] = mb_encode_mimeheader($a)."<hoge@hoge.com>";
mb_internal_encoding($def_encoding);
本当は、1行が76文字以下でなければならないだが、mb_encode_mimeheaderがそれも処理してくれる模様。
あ、でも、fromだけでいいのか?ああ、fromは必須ヘッダだからか?
いや他のヘッダも本当は同様にしなくてはいけない。
他のヘッダーもちゃんとmimeエンコードしておかないとホントはまずい。。てことか。
今はマルチバイトコードのまま、sendmaneに渡しちゃっているんだ。。。
つまりRFC822に準拠していないメールも、親切なメーラーさんのおかげて読めるわけだ。
しかし、人の親切に頼ってばかりはいけないので、ちゃんとエンコードしましょうね。
自宅でのテスト用にwindowsにてサーバーを立ち上げて、sendmane(sendまね~る)という便利なソフトを使わせていただいてる。
通常のmail関数やmb_sendmailはこれで使えるのだけれど、PearのMailを使おうとするとどうしてもエラーがでていた。
apacheのsendmail_pathもちゃんとsendmane用に設定しているので、おそらくPearの方で、独自にsendemailをつついていると考えた。
で、ソースをよくみてみると、pear/Mail/sendemail.php の中にこんな記述が。
var $sendmail_path = '/usr/sbin/sendmail';
ありました、ありました。
これを
var $sendmail_path = 'c:\sendmane\sendmane.exe';に変更して一件落着。(パスはsendmaneのインストールディレクトリによって変わる)
と思って、もう少しソースをたどると
if (isset($params['sendmail_path'])) {
$this->sendmail_path = $params['sendmail_path'];
}
の記述が!
うっソースの修正なんぞしなくても、オプションで設定できたか。
なので、ソースをもとに戻す。そして、呼び出すほうにオプションを設定。
$mail = Mail::factory("sendmail");
だったのを
$mail = Mail::factory("sendmail",array('sendmail_path'=>'c:\sendmane\sendmane.exe'));
に修正。
これでこそ一件落着。
ちなみに、Mailを使ってメールする方法はこちらが丁寧。
http://www.s-memo.net/blog/2007/03/pearmail_1.php
(実はこちらに、オプションの説明があった。。。。)
【環境メモ】
-----------------------------------------------------------
OS:Windows XP SP2
sever:Apache 1.3.37
php:php 5.2.4
pear 1.6.1:Mail 1.1.14,Mail_Mime 1.5.2,DB 1.7.13,XML_RPC 1.5.1
------------------------------------------------------------
