使用PHP imap函数的问题

时间:2010-07-27 20:56:08

标签: php imap

我正在尝试为我们的网站构建电子邮件解析器。我最终要做的是遍历带附件的邮件,如果邮件来自特定的电子邮件地址,则保存附件。

这只是初步测试,但是,我遇到了问题,请参阅下面的评论。

  <?php
  echo "Loading..."."<br />\n";
  $mailuser="help@mysite.com";

  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";;
?>

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

我遇到的最后一个问题是知道FILE与我刚刚打开的消息有什么关系。我知道我可以使用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="help@myserver.com";
  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);  
?>

答案 2 :(得分:0)

问题是我没有检查此行中的imap邮箱:

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

这是正确使用的行:

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