2010-07-27 91 views
0

我正在尝试为我们的网站构建电子邮件消息解析器。如果邮件来自特定的电子邮件地址,我最终要做的是遍历包含附件的邮件并保存附件。使用PHP imap功能的问题

这只是最初的测试,但是,我遇到了问题,请参阅下面的注释。

<?php 
    echo "Loading..."."<br />\n"; 
    $mailuser="[email protected]"; 

    echo "User=$mailuser"."<br />\n";; 
    $mailpass="mypassword"; 
    echo "Pass=$mailpass"."<br />\n"; 
    // had to use this because we have SSL on site and regular port 110 didn't work 
    $mailhost="{localhost:995/pop3/ssl/novalidate-cert}"; 
    echo "Host=$mailhost"."<br />\n"; 

    $mailbox=imap_open($mailhost,$mailuser,$mailpass) or die("<br />\nFAILLED! ".imap_last_error()); 
    $check = imap_check($mailbox); 
    // last message parsed will be stored in the file msgcounter.dat 
    $firstmsg = file_get_contents('msgcounter.dat') + 1; 
    $lastmsg = $firstmsg+$check->Recent; // should be == last msg index + count of latest messages 
    echo 'First:'.$firstmsg.' - Last:'.$lastmsg."<br>"; 
    $result = imap_fetch_overview($mailbox,"$firstmsg:$lastmsg"); 
    print_r($result); 
    foreach ($result as $overview) { 
    echo "#{$overview->msgno} ({$overview->date}) - From: {$overview->from} 
    {$overview->subject}\n"; 
    } 
    // the following approach didn't work either, Kept getting warnings about 
    // Bad message number 
    // 
    // Some messages in the sequence HAVE been deleted. 
    /* 
    for ($index = $firstmsg-1; $index <= ($lastmsg); $index++) { 
    if (strlen(trim(imap_fetchheader($mailbox, $index))) > 0) { 
     echo 'in message index loop:'.$index; 
    } 
    } 
    */ 
    imap_close($mailbox); 
echo "completed.". "<br />\n";; 
?> 
+2

你在问什么? – funwhilelost 2010-07-27 21:09:03

+0

你没看过我的整篇文章吗?如果是这样,你知道哪部分不了解? – MB34 2010-07-29 03:44:19

+0

在阅读您的文章两次后,我找不到明确的问题。我相信你的代码有一些问题,但是直到我们运行代码之前,我们都不知道它是什么。它是注释部分吗?它在别的地方吗? – deceze 2010-07-29 04:03:13

回答

0

的问题是,我没有检查IMAP邮箱在这条线:

$mailhost="{localhost:995/pop3/ssl/novalidate-cert}";

这是使用正确的行:

$mailhost="{localhost/imap/ssl/novalidate-cert}";

0

IMAP是恶劣的标准和恶劣实施的污水池。如果你不介意有点亵渎(或呃,很多),有一些臭名昭着的IMAP rant by a Ruby library dev有一些有趣的见解。

你应该考虑using someone else's code做肮脏的工作。

+0

我的代码是基于我在互联网上找到的一些其他代码,当然... ;-) – MB34 2010-07-29 03:44:50

+0

Ooooo,eeeek,不是Zend的功能! – MB34 2010-07-29 03:45:15

+0

红宝石咆哮很有趣。现在,如果SMTP工作组能够掀起屁股让继电器可验证,那么这将终止垃圾邮件! – MB34 2010-07-29 03:47:43

0

好的我现在有很大一部分工作要做。 我留下的唯一问题实际上是将邮件移动到另一个“文件夹”。 imap_mail_move在POP3邮箱不支持,我不得不想出一个不同的做事方式。

我所知道的最后一个问题是知道什么消息文件与我刚刚打开的消息一起发送。我知道我可以使用std rename()函数来移动文件,但是我发现我可以在courierimapuiddb文件中查找msgnum,并且文件名将会在那里。

这里是我现在使用的代码,与文件的移动除外:

<?php 

function showProgressMsg($msg) 
{ 
    echo $msg."<br>"; 
    ob_flush(); 
flush(); 
    usleep(2500); 
} 
    $mailpass="mymailpass"; 
    $mailhost="{localhost:995/pop3/ssl/novalidate-cert}"; 
    $mailuser="[email protected]"; 
    include "libs/database/db_mysql.php"; 
    $db = new Database; 

    $debug=false; 
    if($_GET['debug']= 'yes') { 
    $debug = true; 
    ini_set('output_buffering', 'Off'); 
    ob_start(); 
    } 

    if($debug) {showProgressMsg('Opening Mailbox');} 

    $mailbox=imap_open($mailhost,$mailuser,$mailpass) or die("<br />\nFAILLED! ".imap_last_error()); 

    // The IMAP.xml file contains the email address and user_id of the users that we accept 
    // their files via email 
    if($debug) {showProgressMsg('Reading IMAP.xml');} 
    $xml = simplexml_load_string(file_get_contents('IMAP.xml')); 
    $result = $xml->xpath('item'); 
    while(list(, $node) = each($result)) { 
    $email = $node->LI_email; 
    $user_id = $node->LI_user_id; 
    $search = "RECENT FROM \"$email\""; 

    if($debug) {showProgressMsg('Searching for '.$email);} 
    $result2 = imap_search($mailbox, $search); 
    if($result2) { 
     $index = $result2[0]; 
     $structure = imap_fetchstructure($mailbox, $index); 

     $attachments = array(); 
     if(isset($structure->parts) && count($structure->parts)) { 
     if($debug) {showProgressMsg('Handling attachments');} 
     for($i = 0; $i < count($structure->parts); $i++) { 
      $attachments[$i] = array(
      'is_attachment' => false, 
      'filename' => '', 
      'name' => '', 
      'attachment' => ''); 

      if($structure->parts[$i]->ifdparameters) { 
      foreach($structure->parts[$i]->dparameters as $object) { 
       if(strtolower($object->attribute) == 'filename') { 
       $attachments[$i]['is_attachment'] = true; 
       $attachments[$i]['filename'] = $object->value; 
       } 
      } 
      } 

      if($structure->parts[$i]->ifparameters) { 
      foreach($structure->parts[$i]->parameters as $object) { 
       if(strtolower($object->attribute) == 'name') { 
       $attachments[$i]['is_attachment'] = true; 
       $attachments[$i]['name'] = $object->value; 
       } 
      } 
      } 

      if($attachments[$i]['is_attachment']) { 
      $attachments[$i]['attachment'] = imap_fetchbody($mailbox, $index, $i+1, FT_PEEK); 
      if($structure->parts[$i]->encoding == 3) { // 3 = BASE64 
       $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); 
      } 
      elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE 
       $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); 
      } 
      }    
     } // for($i = 0; $i < count($structure->parts); $i++) 
     } // if(isset($structure->parts) && count($structure->parts)) 

     // Now add a record into the file_upload table 
     for($i = 0; $i < count($attachments); $i++) { 
     if (strlen(trim($attachments[$i]['filename'])) > 0) { 
      $path_parts = pathinfo($attachments[$i]['filename']); 
      if($debug) {showProgressMsg('Processing '.$attachments[$i]['filename']);} 
      if(strtolower($path_parts['extension']) == 'zip') { 
      // I am going to do something different with ziped files    
      $filename = 'file_uploads/temp/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension']; 
      $fp = fopen($filename, "w"); 
      fwrite($fp, $attachments[$i]['attachment']); 
      fclose($fp);      
      $zip = new ZipArchive(); 
      if ($zip->open($filename) !== TRUE) { 
       die ('Could not open archive'); 
      } 
      $zippedfile = $zip->statIndex(0); 
      $path_parts = pathinfo($zippedfile['name']); 
      $newfilename = 'file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension']; 
      $zip->extractTo('file_uploads/', $zippedfile['name']); 
      $zip->close();   
      unlink($filename); 
      rename('file_uploads/'.$zippedfile['name'], $newfilename); 
      $filestr = preg_replace('`[\r\n]+`',"\n", file_get_contents($newfilename)); 
      $fp = fopen($newfilename, "w+"); 
      fwrite($fp, $filestr); 
      fclose($fp);      
      // remove the directory from the filename 
      $filename = $user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension']; 
      // Now insert into file_upload table 
      $insert_sql = "INSERT INTO `file_upload` VALUES(NULL,$user_id, '$filename', 0, NOW())"; 
      $db->query($insert_sql) or die("Can't insert record"); 
      } else { 
      $filename = 'file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension']; 
      $fp = fopen($filename, "w"); 
      $attachments[$i]['attachment'] = preg_replace('`[\r\n]+`',"\n",$attachments[$i]['attachment']); 
      fwrite($fp, $attachments[$i]['attachment']); 
      fclose($fp); 
      // remove the directory from the filename 
      $filename = $user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension']; 
      // Now insert into file_upload table 
      $insert_sql = "INSERT INTO `file_upload` VALUES(NULL,$user_id, '$filename', 0, NOW())"; 
      $db->query($insert_sql) or die("Can't insert record:".mysql_error()); 
      } 
     } // if (strlen(trim($attachments['name'])) > 0 
     } // for($i = 0; $i < count($attachments); $i++) 
     // Now move the message to completed uploads mailbox 
     // imap_mail_move copies the message and then sets the deleted flag. 
     // Found out that imap_mail_move is unsupported on POP3 accounts 
     // imap_mail_move($mailbox, "$index", "INBOX/completed+uploads") or die("can't move: ".imap_last_error()); 

     // This is a stop gap to circumvent the message being processed twice 
     // Found out that this also is not supported by POP3 boxes 
     if($debug) {showProgressMsg('Setting \Seen flag');} 
     imap_setflag_full($mailbox, "$index", "\Seen \Flagged"); 

     // This clears out the deleted messages 
     // imap_expunge($mailbox); 

     /* 
     So, I'm going to have to open the courierimapuiddb file and locate the msgnum 
     then get the filename and use rename() to move the file to the completed uploads 
     directory. 
     */ 
    if($debug) {showProgressMsg(',oving message');} 

    } // if($result2) 
    // Now, move the message to completed uploads 
    } // while(list(, $node) = each($result)) 
    if($debug) { 
    showProgressMsg('Closing mailbox and cleaning up'); 
    ob_flush(); 
    flush(); 
    ob_end_clean(); 
    ini_set('output_buffering', 4096); 
    } 
    imap_close($mailbox); 
?>