使用 PHP imap 函数的问题

发布于 2024-09-11 15:23:14 字数 1710 浏览 7 评论 0 原文

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

山川志 2024-09-18 15:23:14

IMAP 是一个低标准和糟糕实施的污水池。如果你不介意一点脏话(或者,呃,很多),有一个臭名昭著的 Ruby 库开发人员的 IMAP 咆哮,其中包含一些有趣的见解。

您可能应该考虑使用别人的代码来做肮脏的事情工作。

IMAP is a cesspool of poor standards and worse implementations. 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.

You should probably consider using someone else's code to do the dirty work.

一枫情书 2024-09-18 15:23:14

好吧,现在我已经完成了我正在努力做的大部分工作。
我剩下的唯一问题实际上是将邮件移动到另一个“文件夹”。
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="[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);  
?>

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.

The last problem I have is knowing what message FILE goes with what message that I have just opened. 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.

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="[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);  
?>
苏辞 2024-09-18 15:23:14

问题是我没有在这一行中检查 imap 邮箱:

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

这是要使用的正确行:

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

The problem was that I wasn't checking the imap mailbox in this line:

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

This is the correct line to use:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文