- 締切済み
空メールからの標準入力が受け取れません。
よろしくお願いいたします。 CentOS5.2 & PHP5(お名前.COMのVPSディフォルトです。) お名前.COMのVPSで空メールでのユーザー認識したいと思って います。説明いただいているサイトを参考に、以下のコードを動かして います。 空メールを送ってみると、 $sss=file_get_contents("php://stdin"); をコメントアウトしない場合は、 テストで作らせているテキストファイルもでき、返信メールが帰ります。 しかし、上記文を入れるとテストで作らせているテキストファイルも 返信もありません。 アドバイスいただければ助かります。 pearは Mail_Mime 1.8.0 stable Mail_mimeDecode 1.5.4 stable でインストールしてあります。 <?php //PEARのライブラリ読み込み require_once("/usr/share/pear/Mail/mimeDecode.php"); //メールソースを標準入力から読み込み $sss=file_get_contents("php://stdin"); $frm="AAAAAA"; if(!$source) { exit(); // 読み込み失敗 } //メール解析 $params['include_bodies'] = true; $params['decode_bodies'] = true; $params['decode_headers'] = true; $decoder = new Mail_mimeDecode($sss); $structure = $decoder->decode($params); $from = mb_convert_encoding(mb_decode_mimeheader($structure->headers['from']), mb_internal_encoding(), "auto"); $gdata="ddddddd".$sss.$frm; $ffp2="ggg.txt"; $fh=fopen($ffp2,"w"); fwrite($fh,$gdata); fclose($fh); $from="xxxxx@hhhhh.com"; //メール返信 $to = $from; $title = "空メールの返信(例)"; $body = "登録が完了しました。\n(実際は何も登録していません。)\n※このメールは配信専用です。\n返信されても対応は出来ませんので、ご了承下さい。"; $from = "From: support@XXXXXXXXX"; mb_internal_encoding("SJIS"); mb_language("japanese"); mb_send_mail($to, $title, $body, $from); ?>
- みんなの回答 (8)
- 専門家の回答
みんなの回答
- taka451213
- ベストアンサー率47% (436/922)
こんばんは。 >Object id #2 >が >$structure = $decoder->decode($params); >の答えですが、これで標準入力を受けているということで >よろしいでしょうか。 うーん・・・、一応idが割り振られているので、存在はしていると思います。 $structureをくっつけるより、$structure->headers['from']とかって付けてみた方がいいかと・・・。 まぁ大丈夫だと思いますが、どっちみちこのままじゃぁ、返信はできないので。
- taka451213
- ベストアンサー率47% (436/922)
こんにちは。 >それでも動作していないので、 うーん・・・。 /etc/aliasesを編集した後、更新かけてますよね? それでだめならpostfixをリロードしてみるとか・・・。 >いろいろ、調べてみましたが、etc/aliasesに >touroku: "| /usr/bin/php /var/www/vhosts/url**.com/httpdocs/regist/simp.php" >のように、書くだけで動作するようですので phpのパスは、あくまでもサーバーに合わせてください。 本当に/usr/bin/phpで合ってますか? それでも動かない場合は・・・、ちょっとわかりません・・・。
お礼
ご回答本当に、ありがとうございます。 お礼が遅れて申し訳ありません。 アドバイスいただいた事項を参考に試行錯誤しておりました。 やっと、空メールに対してスクリプトが動作するようになりました。 行ったことを参考とて記させていただきます。 virtual_alias_maps に #vi /etc/postfix/virtual_alias_maps として touroku@url***.com regist_xx を書き加え aliases に #vi /etc/aliases で regist_xx: “|php /var/www/vhosts/url**.com/httpdocs/regist/regi.php" を書き加え # newaliases #/usr/sbin/postmap /etc/postfix/virtual_alias_maps # etc/rc.d/init.d/postfix restart として スクリプトのコードを以下のように書きました。 #!/usr/bin/php -q <?php //PEARのライブラリ読み込み require_once("/usr/share/pear/Mail/mimeDecode.php"); //メールソースを標準入力から読み込み $source =fopen("php://stdin", "r"); //メール解析 $params['include_bodies'] = true; $params['decode_bodies'] = true; $params['decode_headers'] = true; $decoder = new Mail_mimeDecode($source); $structure = $decoder->decode($params); //メール返信 $to = "jibun@url**.com"; $title = "空メールの返信(例だよ)"; $body = "登録が完了しました。\n(実際は何も登録していません。)\n※このメールは配信専用です。\n返信されても対応は出来ませんので、ご了承下さい。\n".$structure; $from = "From: ccc.com"; mb_internal_encoding("SJIS"); mb_language("japanese"); mb_send_mail($to, $title, $body, $from); ?> これで空メールを送ると ------------------------------------------- 登録が完了しました。 (実際は何も登録していません。) ※このメールは配信専用です。 返信されても対応は出来ませんので、ご了承下さい。 Object id #2 -------------------------------------------- にメールが自分に返るようになりました。 試行錯誤で、main.cf の default_privs=apache などを変更しても .forwardを “|php /var/www/vhosts/url**.com/httpdocs/regist/regi.php" として tourokuのMaildirに 行ってもだめでしたが、上記でやっとスクリプトが実行 されたようです。 Object id #2 が $structure = $decoder->decode($params); の答えですが、これで標準入力を受けているということで よろしいでしょうか。
- taka451213
- ベストアンサー率47% (436/922)
こんにちは。 >touroku: "| /var/www/vhosts/url**.com/httpdocs/regist/simp.php" これじゃぁ駄目です・・・。 PHPのパスが書いてないので、ただファイルが呼ばれてるだけ・・・。 パスが通っている場合は、 touroku: "| php /var/www/vhosts/url**.com/httpdocs/regist/simp.php" とか。 phpだけで認識しない場合は、 touroku: "| /usr/bin/php /var/www/vhosts/url**.com/httpdocs/regist/simp.php" とか・・・。
お礼
ご返答、アドバイス本当にありがとうございます。 アドバイスいただいたようにして実験してみました。 それでも動作していないので、下記のように標準入力を コメントアウトしてみました。 この状態でも、動作しませんでした。 ちなみに、ブラウザから http://url**.com/regist/simp.php とすると動作しました。 やはりpostfixからキックしていないのでしょうか。 いろいろ、調べてみましたが、etc/aliasesに touroku: "| /usr/bin/php /var/www/vhosts/url**.com/httpdocs/regist/simp.php" のように、書くだけで動作するようですので、VPSサーバの何かの問題なのでしょうか。 <? php //PEARのライブラリ読み込み //require_once("/usr/share/pear/Mail/mimeDecode.php"); //メールソースを標準入力から読み込み //$source = file_get_contents("php://stdin"); //if(!$source) { // exit(); // 読み込み失敗 //} $gdata="ddddddd".$sss.$frm; $ffp2="ggg.txt"; $fh=fopen($ffp2,"w"); fwrite($fh,$gdata); fclose($fh); //メール返信 $to = "oozora@url**.com"; $title = "空メールの返信(例)"; $body = "登録が完了しました。"; $from = "From: ccc.com"; mb_internal_encoding("SJIS"); mb_language("japanese"); mb_send_mail($to, $title, $body, $from); ?>
- taka451213
- ベストアンサー率47% (436/922)
こんにちは。 そもそも、postfixからどのようにキックしてるんですか? 多分そこの書き方がおかしいので、標準入力に渡ってきてないような・・・?
お礼
ご回答ありがとうございます。 postfixには、VPSのサーバナビというツールで メールユーザーの登録をしています。 touroku@url**.com として登録しています。 /etc/aliasesには touroku: "| /var/www/vhosts/url**.com/httpdocs/regist/simp.php" と書いています。url**はドメインです。 OSのユーザにはtourokuというユーザはありません。 以前使用していたサーバ(CentOS5.1+php5.1.6+sendmail)ではユーザー登録をすると メールユーザーになって、/home/ユーザーのように なっていたのですが、現在のVPSではユーザー作成ではメールユーザー にはなりません。この違いでしょうか。 また、aliasesにtourokudではなくtouroku@url***.comとしなければいけない のでしょうか。 アドバイスよろしくお願いいたします。
- taka451213
- ベストアンサー率47% (436/922)
こんにちは。 >標準入力に(php://stdin)値があるかの >確認はできるのでしょうか。 空メールの受信でキックされるので、デバッグは難しいですね・・・。 ただ、file_get_contents("php://stdin"); に値が入っているかどうかを確認するために、 $stdin = file_get_contents("php://stdin"); $output = "STDIN={$stdin}"; $file = fopen("適当な出力ファイル", "w"); fwrite($file, $output); fclose($file); だけを記述してみて、適当な出力ファイルの中を見てみてはいかがでしょうか? MTAが何か分かりませんが、メールからPHPに渡しているところが問題のような気がしますが・・・?
お礼
ご回答ありがとうございました。 ご呈示いただいた、コードを参考に $stdin = file_get_contents("php://stdin"); $output = "STDIN={$stdin}"; $file = fopen("ggg.txt", "w"); fwrite($file, $output); fclose($file); として、実験しましたが、ggg.txtは生成されて いませんでした。 MTAはpostfixとdovecotです。 VPSの内部設定でしょうか。
- taka451213
- ベストアンサー率47% (436/922)
こんばんは。 file_get_contents("php://stdin"); この使い方は正しいです。 $sss=file_get_contents("php://stdin"); そもそも、$sssに値が入ってないんじゃないですか? file_get_contents("php://stdin"); があるから動かないんじゃなくて、値が入ってきていないから動かないのでは???
お礼
ご回答ありがとうございます。 標準入力に(php://stdin)値があるかの 確認はできるのでしょうか。 空メールにはFromはあると思うのですが。 よろしくお願いいたします。
- bm_hiro
- ベストアンサー率51% (200/388)
とりあえず、文脈が分かりづらいというのは俺も思いました。 一言で言うと、「$sss=file_get_contents("php://stdin"); 」の部分でコケてるっぽい。って事でしょうか? この書き方は極めて一般的な書き方で、問題はないはずです。 実際、俺も これで動かしています。 このソースであるなら、本来 「if(!$source) {」 の部分は、「if(!$sss) {」と するべき所なんでしょうが、今回の問題とは関係ないようなので、置いておきます。 思いつきで書いてるので、アテにはなりませんが、file_get_contents() を file() に置き換えた場合、どうなるでしょう? 関数がダメでコケてるのか、標準入力から取ろうとしている事がダメでコケてるのか分かりませんが、エラーログリポート出してみては如何でしょうか?
お礼
ご返答ありがとうございます。 $sss=file_get_contents("php://stdin"); を $sss=fopen('php://stdin', 'r'); で試してみましたが、同じでした。 /var/log/httpd/error_logを viでみましたが該当するログがありませんでした。 ほかにあるのでしょうか? よろしくお願いいたします。
補足
補足させて頂きます。 $sss=file_get_contents("php://stdin"); を $sss = file('php://stdin'); に変更してみましたが 結果は同じでした。 よろしくお願いいたします。
- taka451213
- ベストアンサー率47% (436/922)
こんにちは。 ちょっと質問の文脈がわかり難いですね・・・。 if(!$source) { exit(); // 読み込み失敗 } で必ずexit()になりそうですが・・・?
お礼
ご返答ありがとうございます。 ご指摘の部分をコメントアウトしても動作しません。 間違えて次の質問で出してしまいましたが、標準入力 を受ける $sss=file_get_contents("php://stdin"); があると、動作しないようです。 アドバイスいただければ助かります。
お礼
ご回答ありがとうございます。 長い間アドバイス本当にありがとうございます。 以下のコードで、無事に空メールを送信した自分に 返信が正常に届きました。 ご親切なアドバイスがなければ、ここまでたどり着く ことができませんでした。VPSの業者はサポート範囲外 ということで、的確な返答がなく taka451213様のアドバイスで、くじけずに進めました。 ここまできて感じますが、VPSの設定でPostfixでありながら sendmailのsmrshが有効になっているような気がしています。 本当にありがとうございました。 #!/usr/bin/php -q <?php //メールソースを標準入力から読み込み $source =fopen("php://stdin", "r"); $email = ""; while ($line = fgets($source)) { $line = trim($line); // メールヘッダ部が終了したらループ終了 if (!$line || $email){ break; } // 送信元メールアドレスの取得 if (eregi("^from:", $line)){ $email = getEmail($line); } } //メール返信 $to=$email; $title = "空メールの返信(テスト例)"; $body = "登録が完了しました。\n(実際は何も登録していません。)\n※このメールは配信専用です。\n返信されても対応は出来ませんので、ご了承下さい。\n"; $from = "From:info-xxx@url**.com"; mb_internal_encoding("SJIS"); mb_language("japanese"); mb_send_mail($to, $title, $body, $from); function getEmail($line) { if (eregi("(.*)\<(.*)\>", $line, $tmp)){ $fromx = $tmp[2]; } return strtolower(trim($fromx)); } ?>