人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

◆急いでいます。PHPでメール解析

PHPでメール解析をする際、GMAILやYahooメールなどは、Fromが取得出来なくて困っています。

現在、以下のようなスクリプトで解析を行っています。

eregi( "From:[ \t]*([^\r\n]+)", $head, $freg )
でFrom:が入っていたら
eregi( "[-!#$%&\'*+\\./0-9A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+", $addr, $fromreg)を実行し、
$fromreg[0]を取りだして使っています。

しかし、この方法だと、GMAILなどで、FROM:の前に文字列が入っている場合、うまくメールアドレスが取得できません。


出来れば、上記の方法を修正したやり方でご教授頂ければ幸いです。

よろしくお願い致します。

●質問者: KENJI0620
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● だわかき
●50ポイント

eregiではなくpreg_matchを使ったらどうでしょう。
スクリプトはUTF-8で保存し、FROM:の後の部分もUTF-8にしてください。

<?php
mb_internal_encoding('utf-8');

$addr = FROM:の後の部分

$pat = "/([0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+@[0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+)/ui";
preg_match($pat, $addr, $formreg);

echo $formreg[1];
?>

KENJI0620さんのコメント
ご回答ありがとうございます。 もし、スクリプトをUTF-8では無く、Shifut-JISで保存しなければならない場合は、どうしたら良いでしょうか? 上記のスクリプトを入れる前に、UTF-8で保存したら、完璧に文字化けしました。 ご教示の程、よろしくお願い申し上げます。 ちなみに、Apach2、PHP5.3.3、MySQLはUTF-8で、MySQLに格納してあるデータを空メールに返信したいと考えております。 PCメールやガラケーは問題ありませんでした。 GMAIL、Yahoomail、auの携帯がエラーです。 何卒、よろしくお願い申し上げます。

だわかきさんのコメント
シフトJISだとpreg_matchがうまく動かない場合があります。メールアドレスの前に日本語が含まれている場合などです。 PHPはUTF-8が推奨されているので、シフトJISはやめたほうがいいです。 MySQLもUTF-8なら、スクリプトをシフトJISにする必要性はないと思います。

KENJI0620さんのコメント
教えてもらったスクリプトを使ってみたのですが、 通常のメールでは問題無くても、YahooやGmailはFromが取得できません。 <?php mb_internal_encoding('utf-8'); if ( eregi( "From:[ \t]*([^\r\n]+)", $head, $freg ) ){ $addr = addr_search($freg[1]); } function addr_search( $addr ){ $pat = "/([0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+@[0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+)/ui"; preg_match($pat, $addr, $formreg); echo $formreg[1]; } ?> pearやその他のクラスなどを使わないプレーンなPHPでのやり方を、再度ご教示頂ければと思います。 よろしくお願い致します。

KENJI0620さんのコメント
すみません。追加で作業をしてみました。 関連の全てのPHPファイル等をUTF-8にして動かしてみたのですが、 やはり、正常に動作しません。 ちなみに、このスクリプトは、PHP5.1の段階では正常に動作していたのですが、 サーバを変更して、PHP5.3.3になったとたんにエラーになってしまいました。 是非、ご教授頂けると助かります。 何卒、よろしくお願い申し上げます。

KENJI0620さんのコメント
何度もすみません。追加で色々やってみた所、 mailboxに入っている状態のデータでは、正常にFromにメールアドレスがありますが、 POPでつなぎに行ってから、格納された情報をダンプしてみた所、 From:○○ しか無く、肝心の<○○@aaa.com>のアドレスが入っていません。 これが原因だとすれば、このスクリプトの手前の、POPでつなぎに行って、メール本文を取得してくる所から間違っているような気がします。 是非、ご教授頂けると助かります。 初心者なので、よろしくお願い致します。

だわかきさんのコメント
POPでつなぎに行って、メール本文を取得してくる所から間違っているのだと思います。 そのスクリプトを示していただかないと、アドバイスできません。

KENJI0620さんのコメント
ご返信ありがとうございます。 POPの接続から各処理までは、以下になります。 $sock = fsockopen( $host, 110, $err, $errno, 10 ); if ( !$sock ){ output_log( "POPサーバー接続エラー/$err/$errno" ); die; } $buf = fgets( $sock ); if ( substr($buf, 0, 3) != '+OK'){ output_log( $buf ); die(); } $user = $corner_array[$i]['user']; $pass = $corner_array[$i]['pass']; $category = $corner_array[$i]['category']; $buf = _sendcmd( "USER $user" ); $buf = _sendcmd( "PASS $pass" ); $data = _sendcmd( "STAT" ); sscanf( $data, '+OK %d %d', $num, $size ); if ( $num == "0" ){ $buf = _sendcmd( "QUIT" ); fclose( $sock ); continue; } for ( $i = 1; $i <= $num; $i ++ ){ $line = _sendcmd( "RETR $i" );) while ( !preg_match( "/^\.\r\n/i", $line ) ){ //EOFの.まで読む $line = fgets( $sock, 512 ); $dat[$i].= $line; } $data = _sendcmd( "DELE $i" ); } $buf = _sendcmd("QUIT"); fclose( $sock ); // 送信者アドレスの抽出 if ( preg_match( "/From:[ \t]*([^\r\n]+)/i", $head, $freg ) ){ $from = addr_search($freg[1]); } elseif ( preg_match( "/Reply-To:[ \t]*([^\r\n]+)/i", $head, $freg ) ){ $from = addr_search($freg[1]); } elseif ( preg_match( "/Return-Path:[ \t]*([^\r\n]+)/i", $head, $freg ) ){ $from = addr_search($freg[1]); } ※基本的に、空メールを送信し、自動的に返信するスクリプトです。 ※通常のパソコンメール(フリーメール以外、携帯メールも含む)では、 正常にFromのアドレスが取得でき、返信出来ます。 ※しかし、YahooメールやGmailは自動返信されません。 ※サーバからmailコマンドでの送信は正常に送れます。 ※ヘッダーをダンプした際は、パソコンや携帯メールでも、Fromの後に文字列は入っていませんが、正常に自動返信されました。 ※スクリプトは、全てUTF-8で保存しています。 以上が全要です。 ご教授の程、よろしくお願い致します。

だわかきさんのコメント
そのソースでは $head には何も入っていないことになります。 ソースが違うのではないですか?

2 ● だわかき
●50ポイント

PHP5.3ではeregiは使えません。
上で回答したようにpreg_matchを使ってください。

mb_internal_encoding('utf-8');

$pat = "/From:[ \t]*([^\n]+)/msui";
if (preg_match($pat, $head, $freg ) ){
 $addr = addr_search($freg[1]);
}

function addr_search( $addr ){
 $pat = "/([0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+@[0-9a-z!#\$%\&'\*\+\/\=\?\^\|\-\{\}\.]+)/ui";
 preg_match($pat, $addr, $formreg);
 echo $formreg[1];
}
?>

KENJI0620さんのコメント
ご教授ありがとうございます。 上記の通りやってみましたが、やはり、YahooやGmailの送信元のアドレスは取得出来ませんでした。 ちなみに、全てUTF-8にてやりなおしています。 通常のメールでの送信は正常に動作しております。 引き続き、ご教授の程、よろしくお願い申し上げます。

KENJI0620さんのコメント
★追記です。通常のメールヘッダーをみますと、From:"kenji" <kenji@aaa.com>となっていて、YahooやGmailでは、From:kenji <kenji@aaa.com>となっています。 つまり、""が入っている(もしくは単純な<kenji@aaa.com>)だと取得できるのですが、””で区切られていないで送信者名が入っているとエラーになるみたいです。 是非、回避の方法をご教授頂けます様お願い申し上げます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ