За последние 24 часа нас посетили 16270 программистов и 1581 робот. Сейчас ищут 1617 программистов ...

Парсинг писем

Тема в разделе "Работа с почтой", создана пользователем barnaulez, 24 июл 2014.

  1. barnaulez

    barnaulez Новичок

    С нами с:
    24 июл 2014
    Сообщения:
    1
    Симпатии:
    0
    Доброго времени!
    На сайте, сделанном на джумле, есть самописный модуль. Суть его в следующем:
    На определенный почтовый адрес приходят письма. Модуль по расписанию раз в пять минут просматривает этот адрес и парсит письма от определенных адресатов. В письме содержатся курсы валют банков.
    После обновления php до 5.4.29 некоторые письма перестали парситься и в курсы встают пустые значения.
    Была выявлена закономерность: письма, приходящие в utf8 - это те, которые некорректно парсятся. Те же, которые были в koi-8 - с ними все хорошо.
    Где копать? совершенно не понятно.
    Код (Text):
    1. <?
    2. //error_reporting(0);
    3.  
    4. /* Constants */
    5. define('MOD_PROTECT',true);
    6. setlocale(LC_ALL,'ru_RU.CP1251');
    7.  
    8. define('ADODB_ASSOC_CASE',0); // sets all returned column names to Lower
    9.  
    10. require_once('adodb/adodb.inc.php');
    11. require_once('rfc822_addresses.php');  
    12. require_once('mime_parser.php');  
    13. require_once('mimedecode.inc.php');  
    14. require('config.php');
    15.  
    16. $db = NewADOConnection('mysql');
    17. //$db->debug = true;
    18. if (!$db)
    19.     die("Connection failed");
    20. $db->Connect($sql_server,$sql_login,$sql_password,$sql_db);
    21. unset($sql_login,$sql_password);
    22.  
    23. $db->SetFetchMode(ADODB_FETCH_ASSOC);
    24.  
    25. $mime = new mime_parser_class;  
    26. $mime->decode_bodies = 1;
    27. $mime->ignore_syntax_errors = 0;
    28.  
    29. $server = 'localhost';
    30. $port = 110;
    31. $login = 'kurs';
    32. $pass = 'IIQ2Vn7zEHRTMfC';
    33.  
    34. $pop_conn = fsockopen($server, $port, $errno, $errstr, 10);
    35. $code = fgets($pop_conn,1024);
    36. fputs($pop_conn,"USER $login\r\n");
    37. $code = fgets($pop_conn,1024);
    38. fputs($pop_conn,"PASS $pass\r\n");
    39. $code = fgets($pop_conn,1024);
    40.  
    41. fputs($pop_conn,"STAT\r\n");
    42. $code = fgets($pop_conn,1024);
    43.  
    44. $code = explode(" ",$code);
    45. $msg_count = intval($code[1]);
    46. echo "<date>".date("Y-m-d H:i:s")."</date>";
    47. echo "<countNewMessage>Новых сообщений: $msg_count</countNewMessage>";
    48. if($msg_count < 1)
    49.     echo "<result>Процедура завершена.</result>";
    50.  
    51. for($i = 1;$i <= $msg_count; $i++) {
    52.     $results = array();
    53.     echo "<msgNum>Сообщение $i</msgNum>";
    54.     fputs($pop_conn,"RETR $i\r\n");
    55.     $text = get_data($pop_conn);
    56.     $msg_subject = '';  
    57.     if ($mime->Decode(Array('Data' => $text), $decoded)) {  
    58.         if ($mime->Analyze($decoded[0], $results)) {  
    59.     //      $msg_subject = $results['Subject'];  
    60.         }
    61.     }
    62.     $email_from = $results['From'][0]['address'];
    63.     $encoding=$results['Encoding'];
    64.     //$data=$results['Data'];
    65.     $text = eregi_replace("\<br\>","\n",$text);
    66.    
    67.     /*******/
    68.     if($kurs_fulllog == "1") {
    69.         $title = 'test_abs';
    70.         //$mess =  'test_abs_message';
    71.         $to = '@@@@gmail.com';
    72.         $from='debug@alt-banks.ru';
    73.         mail($to, $title, $text, 'From:'.$from);
    74.     }
    75.    
    76.     $mimedecoder = new MIMEDECODE($text,"\r\n");
    77.     $data = $mimedecoder->get_parsed_message();
    78.     $data = strip_tags($data);
    79.     if(strlen($data)<30)
    80.         $data=$text;
    81.  
    82.     if(eregi("utf-8", $encoding))
    83.         $data = iconv("utf-8", "windows-1251",$data);
    84.     if(eregi("koi8-r", $encoding))
    85.         $data = iconv("koi8-r", "windows-1251",$data);
    86.  
    87.     // replace unconverted symbols
    88.     $data = str_replace("=3D","=",$data);
    89.     $data = str_replace("=5F","_",$data);
    90.    
    91.     $data = eregi_replace("\<br\>","\n",$data);
    92.  
    93.     if($kurs_fulllog == "1") {
    94.         $rand=md5(rand(100000,1).microtime());
    95.  
    96.         if(!is_dir($kurs_logdir.date("Ymd"))) {
    97.             mkdir($kurs_logdir.date("Ymd"));
    98.             chmod($kurs_logdir.date("Ymd"),0777);
    99.         }
    100.  
    101.         $fname = $kurs_logdir.date("Ymd")."/".$rand.".msg";
    102.  
    103.         $ffile = fopen($fname,"a");
    104.  
    105.         if($ffile) {
    106.             fputs($ffile, "From: $email_from\n");
    107.             fputs($ffile, "Encoding: $encoding\n");
    108.             fputs($ffile, "Parsed:\n$data\n");
    109.             fputs($ffile, "Source:\n$text");
    110.         }
    111.     }
    112.  
    113.     process_letter($data, $email_from);
    114.     if($kurs_fulllog == "1")
    115.         fclose($ffile);
    116.  
    117.     fputs($pop_conn, "DELE $i\r\n");
    118.     $code = fgets($pop_conn,1024);
    119. }
    120.  
    121.  
    122. fputs($pop_conn,"QUIT\r\n");
    123. $code = fgets($pop_conn,1024);
    124. fclose($pop_conn);
    125.  
    126. function get_data($pop_conn) {
    127.     $data = "";
    128.     while (!feof($pop_conn)) {
    129.         $buffer = chop(fgets($pop_conn,1024));
    130.         $data .= "$buffer\r\n";
    131.         if(trim($buffer) == ".") break;
    132.     }
    133.     return $data;
    134. }
    135.  
    136. function process_letter($body,$from_email) {
    137.     global $db,$kurs_fulllog,$ffile;
    138.  
    139.     echo "<processHead>Обработка письма от $from_email</processHead>";
    140.     $from_email = trim($from_email);
    141.     if(strlen($from_email)>8) {
    142.         $bankid = intval(get_bankid($from_email));
    143.         if($bankid > 0) {
    144.             echo "<bankId>ID банка: $bankid</bankId>";
    145.             $body = explode("\n",$body);
    146.  
    147.             if($kurs_fulllog == "1") {
    148.             //debug
    149.                 print_r($body);
    150.             }
    151.            
    152.             foreach($body AS $str) {
    153.                 if(eregi("USD_BUY=",$str) && !$usd_buy) {
    154.                     $str = str_replace(",",".",$str);
    155.                     $usd_buy = eregi_replace("(.*)USD_BUY=([0-9.,]*)(.*)","\\2",$str);
    156.                     $usd_buy = str_replace('..', '.', $usd_buy);
    157.                     echo "<course>USD покупка: $usd_buy</course>";
    158.                 } elseif(eregi("USD_SELL=",$str) && !$usd_sell) {
    159.                     $str = str_replace(",",".",$str);
    160.                     $usd_sell = eregi_replace("(.*)USD_SELL=([0-9.,]*)(.*)","\\2",$str);
    161.                     $usd_sell = str_replace('..', '.', $usd_sell);
    162.                     echo "<course>USD продажа: $usd_sell</course>";
    163.                 } elseif(eregi("EURO_BUY=",$str) && !$euro_buy) {
    164.                     $str = str_replace(",",".",$str);
    165.                     $euro_buy = eregi_replace("(.*)EURO_BUY=([0-9.,]*)(.*)","\\2",$str);
    166.                     $euro_buy = str_replace('..', '.', $euro_buy);
    167.                     echo "<course>Euro покупка: $euro_buy</course>";
    168.                 } elseif(eregi("EURO_SELL=",$str) && !$euro_sell) {
    169.                     $str = str_replace(",",".",$str);
    170.                     $euro_sell = eregi_replace("(.*)EURO_SELL=([0-9.,]*)(.*)","\\2",$str);
    171.                     $euro_sell = str_replace('..', '.', $euro_sell);
    172.                     echo "<course>Euro продажа: $euro_sell</course>";
    173.                 } elseif(eregi("KZT_BUY=",$str) && !$kzt_buy) {
    174.                     $str = str_replace(",",".",$str);
    175.                     $kzt_buy = eregi_replace("(.*)KZT_BUY=([0-9.,]*)(.*)","\\2",$str);
    176.                     $kzt_buy = str_replace('..', '.', $kzt_buy);
    177.                     echo "<course>KZT покупка: $kzt_buy</course>";
    178.                 } elseif(eregi("KZT_SELL=",$str) && !$kzt_sell) {
    179.                     $str = str_replace(",",".",$str);
    180.                     $kzt_sell = eregi_replace("(.*)KZT_SELL=([0-9.,]*)(.*)","\\2",$str);
    181.                     $kzt_sell = str_replace('..', '.', $kzt_sell);
    182.                     echo "<course>KZT продажа: $kzt_sell</course>";
    183.                 } elseif(eregi("CNY_BUY=",$str) && !$cny_buy) {
    184.                     $str = str_replace(",",".",$str);
    185.                     $cny_buy = eregi_replace("(.*)CNY_BUY=([0-9.,]*)(.*)","\\2",$str);
    186.                     $cny_buy = str_replace('..', '.', $cny_buy);
    187.                     echo "<course>CNY покупка: $kzt_buy</course>";
    188.                 } elseif(eregi("CNY_SELL=",$str) && !$cny_sell) {
    189.                     $str = str_replace(",",".",$str);
    190.                     $cny_sell = eregi_replace("(.*)CNY_SELL=([0-9.,]*)(.*)","\\2",$str);
    191.                     $cny_sell = str_replace('..', '.', $cny_sell);
    192.                     echo "<course>CNY продажа: $kzt_sell</course>";
    193.                 } elseif(eregi("GBP_BUY=",$str) && !$gbp_buy) {
    194.                     $str = str_replace(",",".",$str);
    195.                     $gbp_buy = eregi_replace("(.*)GBP_BUY=([0-9.,]*)(.*)","\\2",$str);
    196.                     $gbp_buy = str_replace('..', '.', $gbp_buy);
    197.                     echo "<course>GBP покупка: $kzt_buy</course>";
    198.                 } elseif(eregi("GBP_SELL=",$str) && !$gbp_sell) {
    199.                     $str = str_replace(",",".",$str);
    200.                     $gbp_sell = eregi_replace("(.*)GBP_SELL=([0-9.,]*)(.*)","\\2",$str);
    201.                     $gbp_sell = str_replace('..', '.', $gbp_sell);
    202.                     echo "<course>GBP продажа: $kzt_sell</course>";
    203.                 } elseif(eregi("CHF_BUY=",$str) && !$chf_buy) {
    204.                     $str = str_replace(",",".",$str);
    205.                     $chf_buy = eregi_replace("(.*)CHF_BUY=([0-9.,]*)(.*)","\\2",$str);
    206.                     $chf_buy = str_replace('..', '.', $chf_buy);
    207.                     echo "<course>CHF покупка: $chf_buy</course>";
    208.                 } elseif(eregi("CHF_SELL=",$str) && !$chf_sell) {
    209.                     $str = str_replace(",",".",$str);
    210.                     $chf_sell = eregi_replace("(.*)CHF_SELL=([0-9.,]*)(.*)","\\2",$str);
    211.                     $chf_sell = str_replace('..', '.', $chf_sell);
    212.                     echo "<course>CHF продажа:</b> $chf_sell</course>";
    213.                 }
    214.             }
    215.  
    216.             $now = date("Y-m-d H:i:s");
    217.             //  $db->debug=true;
    218.  
    219.             if($kurs_fulllog == "1")
    220.                 fputs($ffile, "\nSQL:UPDATE altb_courses SET usd_buy='$usd_buy', usd_sell='$usd_sell', euro_buy='$euro_buy', euro_sell='$euro_sell', kzt_buy='$kzt_buy', kzt_sell='$kzt_sell', cny_buy='$cny_buy', cny_sell='$cny_sell', gbp_buy='$gbp_buy', gbp_sell='$gbp_sell', chf_buy='$chf_buy', chf_sell='$chf_sell', lastupdate='$now' WHERE id='$bankid'");
    221.  
    222.             $req = $db->Execute("UPDATE altb_courses SET usd_buy='$usd_buy', usd_sell='$usd_sell', euro_buy='$euro_buy', euro_sell='$euro_sell', kzt_buy='$kzt_buy', kzt_sell='$kzt_sell', cny_buy='$cny_buy', cny_sell='$cny_sell', gbp_buy='$gbp_buy', gbp_sell='$gbp_sell', chf_buy='$chf_buy', chf_sell='$chf_sell', lastupdate='$now' WHERE id='$bankid'");
    223.             echo "<result>";
    224.             echo ($req) ? "Курсы успешно обновлены!" : "Ошибка обновления курсов (ошибка запроса)";
    225.             echo "</result>";
    226.             //  $req=$db->Execute("INSERT INTO kurs_update SET usd_buy='$usd_buy', usd_sell='$usd_sell', euro_buy='$euro_buy', euro_sell='$euro_sell', kzt_buy='$kzt_buy', kzt_sell='$kzt_sell', cny_buy='$cny_buy', cny_sell='$cny_sell', gbp_buy='$gbp_buy', gbp_sell='$gbp_sell', chf_buy='$chf_buy', chf_sell='$chf_sell', id='$bankid', adddate='$now', userid='0'");
    227.         }
    228.         else
    229.             return;
    230.     }
    231.     else
    232.         return;
    233. }
    234.  
    235. function get_bankid($from_email) {
    236.     global $db;
    237.  
    238.     $from_email = trim(strtolower($from_email));
    239.     $query = $db->Execute("SELECT id, email FROM altb_courses");
    240.     while($array = $query->FetchRow()) {
    241.         extract($array);
    242.         $email = trim(strtolower($email));
    243.         if(eregi(",",$email)) {
    244.             $email = explode(",",$email);
    245.             $email = array_map('trim', $email);
    246.             if(in_array($from_email,$email))
    247.                 return $id;
    248.         }
    249.         else {
    250.             if($email == $from_email)
    251.                 return $id;
    252.         }
    253.     }
    254.     return 0;
    255. }
    256.  
    257. echo "\n\n";
    258. ?>
     
  2. Хыиуду

    Хыиуду Активный пользователь

    С нами с:
    3 июн 2014
    Сообщения:
    618
    Симпатии:
    5
    Во-первых, уходите от функций, начинающихся на ereg, меняйте их на preg, ereg устарело и скоро будет выпилено.
    Во-вторых, давать простыню на несколько десятков килобайт, мол, разбирайтесь сами - это моветон.
    В-третьих, раз уж вы обнаружили источник ошибки (не парсится utf-8, но парсится koi-8, о боги, оказывается, он еще жив) - сделайте iconv обратно в koi-8.
    Ну, и в-четвертых, что-то мне подсказывает, что есть более простые способы получать курсы валют, чем парсить приходящие письма.