简体   繁体   English

使用PHP imap函数的问题

[英]Problem using PHP imap functions

I'm trying to build an email message parser for our site. 我正在尝试为我们的网站构建一个电子邮件解析器。 What I'm eventually going to do is iterate through the messages that have attachments and save the attachment if the message comes from a particular email address. 我最终要做的是遍历具有附件的邮件,如果邮件来自特定的电子邮件地址,则保存附件。

This is just the initial test, however, I am running into problems, see comments below. 这只是初步测试,但是我遇到了问题,请参阅下面的评论。

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

IMAP is a cesspool of poor standards and worse implementations. IMAP是不良标准和较差实施的结果。 If you don't mind a little profanity (or, er, a lot), there's an infamous IMAP rant by a Ruby library dev with some interesting insights. 如果您不介意(或很多)亵渎,那么Ruby库开发人员会提供臭名昭著的IMAP咆哮,其中包含一些有趣的见解。

You should probably consider using someone else's code to do the dirty work. 您可能应该考虑使用其他人的代码来完成肮脏的工作。

Ok I have a big part of what I'm trying to do working, now. 好的,我现在正在努力工作。 The only problem I have left is actually moving the message to another "folder". 我剩下的唯一问题实际上是将邮件移到另一个“文件夹”。 imap_mail_move is not supported on POP3 mailboxes and si I have had to come up with a different way of doing things. POP3邮箱不支持imap_mail_move,因为我不得不提出一种不同的处理方式。

The last problem I have is knowing what message FILE goes with what message that I have just opened. 我遇到的最后一个问题是知道什么消息FILE与刚打开的什么消息一起出现。 I know I can use the std rename() function to move the file but I found that I can lookup the msgnum in the courierimapuiddb file and the filename will be there. 我知道我可以使用std named()函数移动文件,但是我发现可以在courierimapuiddb文件中查找msgnum,文件名就在那里。

Here's the code I now have working, with the exception of the moving of the file: 这是我现在正在使用的代码,但文件的移动除外:

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

The problem was that I wasn't checking the imap mailbox in this line: 问题是我没有在这一行中检查imap邮箱:

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

This is the correct line to use: 这是要使用的正确行:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM