◆急いでいます。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:の前に文字列が入っている場合、うまくメールアドレスが取得できません。


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

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

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2013/05/13 03:11:17
  • 終了:2013/05/20 03:15:03

回答(2件)

id:dawakaki No.1

だわかき回答回数797ベストアンサー獲得回数1222013/05/13 12:17:25

ポイント50pt

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];
?>
他6件のコメントを見る
id: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で保存しています。

以上が全要です。
ご教授の程、よろしくお願い致します。

2013/05/18 23:28:51
id:dawakaki

そのソースでは $head には何も入っていないことになります。
ソースが違うのではないですか?

2013/05/19 08:17:07
id:dawakaki No.2

だわかき回答回数797ベストアンサー獲得回数1222013/05/15 23:13:46

ポイント50pt

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];
}
?>
id:KENJI0620

ご教授ありがとうございます。
上記の通りやってみましたが、やはり、YahooやGmailの送信元のアドレスは取得出来ませんでした。
ちなみに、全てUTF-8にてやりなおしています。
通常のメールでの送信は正常に動作しております。

引き続き、ご教授の程、よろしくお願い申し上げます。

2013/05/16 14:55:17
id:KENJI0620

★追記です。通常のメールヘッダーをみますと、From:"kenji" <kenji@aaa.com>となっていて、YahooやGmailでは、From:kenji <kenji@aaa.com>となっています。
つまり、""が入っている(もしくは単純な<kenji@aaa.com>)だと取得できるのですが、””で区切られていないで送信者名が入っているとエラーになるみたいです。

是非、回避の方法をご教授頂けます様お願い申し上げます。

2013/05/16 15:01:15
  • id:rouge_2008
    FROM:の前の文字列とはどのような文字列でしょう?

    ※ところで、変数名に間違いはありませんか?
    最初は$fregに格納しているようですが、次に$addrからメールアドレスを探しています。

    ※POSIXの正規表現関数はPHP 5.3以降で非推奨になりましたので、PCRE関数を利用した方がいいです。
    http://www.php.net/manual/ja/ref.regex.php

    ・preg_match
    http://www.php.net/manual/ja/function.preg-match.php
  • id: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でのやり方をご教示頂ければと思います。


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

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません