くまきち

山と旅と家族が大事。
でも激しい物欲が理性と財布のタガを飛ばす
最近は自転車も乗ってる

PHP: mail関数

2009-06-07 13:04:48 | SEまわり
たまに、いや、滅多にないけど、 PHP のソースを読むことがある。
趣味ではなく、必要に迫られて。

今日は、mail コマンドの内部動作が、「自力でソケット開いて通信する」のか「システムのmailコマンドを呼ぶ」のか「sendmailを呼ぶのか」を知りたくて、探した。

ソース中の、ext/standard/mail.c がそれ。
コメント入れても340行しかないシンプルなソース。

PHP のソース類は、わりと分かりやすいんじゃないかなと感じる。


動作(UNIX版)は、sendmail コマンド(うちの場合はPostifx 使ってるから、sendmai コマンドは postfix にすり替えられてる)を popen で開いてから、そこにデータを順番に流し込んでるだけだった。


メール送信をするメソッドのテストをするために、「メールを送ったふりをして、送出データ全体(MTAが受け取るデータ全体)をファイルに保存したい」と思ったんだが、sendmail に順番に流し込まれているのなら、途中で捕まえることはできない。残念。


となると、sendmail が送る先を適当なアドレスに変えて、そいつを /etc/aliases にてファイルにリダイレクトするように書くのが適当だな。

それでできると思うけど、テスト用のアドレスって、なんかテストとしては「緩いテスト」だと感じるので、あまり好きじゃないんだよな。 もう一歩進んだところ(実際の送出データがMTAに引き渡される直前)でデータを捕まえて検証したいと思う。

そうすると、前出の mail.c の関数にファイル保存パスを記述するように変更をかけて、再コンパイルする方法を思いつくが、それによる影響を量るのが大変だし、生兵法でけがをするのは困る。

で、考えたのが、mail.c は sendmail のパス情報として、php.ini 中の $sendmail_path を参照している。

じゃあ、ここに自作のコマンドを書いてしまえばイイじゃないですか。

  sendmail_path = "| /usr/local/bin/m2file.pl"
    (なんで Perl ? )

としておいて、m2file.pl で、標準入力に入ってくるデータをそのままどこかのファイルに書き出せばいい。


なんで、こんな簡単なことをすぐに思いつかないのかね。 頭が悪いですね。

でも、ソースを読むのは無駄にならないことだけは確か。