【问题标题】:imap_search limit the number of messages returnedimap_search 限制返回的消息数
【发布时间】:2011-01-11 17:57:48
【问题描述】:

我有一个从邮箱中获取消息的 PHP 脚本。我使用 imap_search 功能: $emails = imap_search($mbox, 'UNSEEN');

有没有办法限制返回消息的数量。现在,在巨大的邮箱中,我收到了大约 5000 条消息。我只想要按日期排序的前 20 个。

有没有办法做到这一点?

谢谢。

【问题讨论】:

    标签: php email imap


    【解决方案1】:

    imap_search 函数有一个 CRITERIA 属性,您可以使用多种方式限制消息:

    ALL - 返回符合其余条件的所有消息
    ANSWERED - 匹配带有 \ANSWERED 标志集的消息
    密件抄送“字符串” - 将消息与密件抄送中的“字符串”匹配:字段
    BEFORE "date" - 匹配消息与 Date: before "date"
    BODY "string" - 匹配消息正文中带有 "string" 的消息
    抄送“字符串” - 将消息与抄送:字段中的“字符串”匹配
    DELETED - 匹配已删除的消息
    FLAGGED - 匹配带有 \FLAGGED(有时称为重要或紧急)标志集的消息
    FROM "string" - 在 From: 字段中匹配带有 "string" 的消息
    KEYWORD "string" - 匹配以 "string" 作为关键字的消息
    新 - 匹配新消息
    OLD - 匹配旧消息
    ON "date" - 匹配带有日期的消息:匹配 "date"
    RECENT - 匹配设置了 \RECENT 标志的消息
    SEEN - 匹配已读取的消息(设置了 \SEEN 标志)
    SINCE "date" - 匹配带有日期的消息:在 "date" 之后
    SUBJECT "string" - 匹配主题中带有 "string" 的消息:
    TEXT "string" - 匹配带有文本 "string" 的消息
    TO "string" - 将消息与 To 中的 "string" 匹配: UNANSWERED - 匹配尚未回答的消息
    UNDELETED - 匹配未删除的消息
    未标记 - 匹配未标记的消息
    UNKEYWORD "string" - 匹配没有关键字"string"的消息
    UNSEEN - 匹配尚未阅读的消息

    【讨论】:

    • 这将缩小搜索范围,但会限制返回多少邮件?
    • @Anthony:据我所知,这是缩小范围的唯一方法。有吗?
    • 缩小范围,这是唯一的方法。但他的标准是我假设的 all 消息的限制数量,imap_search 没有提供。可能会有黑客攻击,请查看我的编辑并告诉我您的想法。
    • 如何获取特定标签的邮件。 ??
    【解决方案2】:

    imap_sort 将允许您同时排序和过滤

    但是,它仍然不允许在函数调用时限制到“前 20”。

    【讨论】:

      【解决方案3】:

      imap_search docs 指出此功能:

      返回消息编号或 UID 的数组。

      imap_fetch_overview 文档表明此函数也返回:

      message_id - 消息 ID, uid - 邮件在邮箱中的 UID

      所以我们可以使用imap_fetch_overview 对某个数字和顺序进行排序,返回与imap_search 函数相同。

      // get information about the current mailbox
      $mboxCheck = imap_check($mbox);
      
      // get the total amount of messages
      $totalMessages = $mboxCheck->Nmsgs;
      
      // select how many messages you want to see
      $showMessages = 20;
      
      // get those messages    
      $result = imap_fetch_overview($mbox($totalMessages-$showMessages+1).":".$totalMessages);
      
      $n = 0;
      $emails = array();
      // loop through returned messages, collect message numbers in same format as output of imap_search
      foreach ($result as $mail) {
          $emails[$n] = $mail->msgno;
          $n++;
      }  
      
      if($emails) {
      // put the newest emails on top 
      rsort($emails);
      }
      

      这是用this answer的概念构建的

      【讨论】:

        【解决方案4】:

        这样解决这个问题:

        1.您可以通过使用 since 标准减少数据数量来限制返回的结果数量 2. 检索最后返回的少数消息,例如 15

        $this->msgCounts = imap_search($imap_resource, 'SUBJECT "hello dolly" SINCE "8 April 2003"', SE_UID);
        

        然后这里是一个示例,用于检索返回的最后 15 个,然后向前和向后切换以查看更多结果或更旧的结果。请注意,这假设您有一个设置 $_GET 变量的向前和更早的按钮。

        $this->msgCounts = $messageCounts;
                $multiarray=[];
                \Session::put('totalmsg',$this->msgCounts);             //Sav etotal no of message in folder to session to determine if to allow next or previous
        
                if($this->msgCounts > 15)                               //MESSAGES IS MORE THAN WE NEED GET 20
                {
                    $offcut = 15;                                       //default offcut
        
                    /**
                    * Viewing previous or next messages
                    **/
                        if(isset($_GET['msgs']) && $_GET['msgs'] == 'older')
                        {
                         $this->msgCounts =  \Cache::has('msgpointer') ? \Cache::get('msgpointer') : $this->msgCounts;
                            $msgOffset = $this->msgCounts - $offcut;    //get +15 messages
        
                            if($offcut > $msgOffset) {
                                $msgOffset = $msgOffset + 5;            //if less than 15 get 10
                                $offcut = 10;
                            }
                            if($offcut > $msgOffset) {
                                $msgOffset = $msgOffset + 5;            //if less than 10 get 5
                                $offcut = 5;
                            }
                            if($offcut > $msgOffset) {
                                $msgOffset = $msgOffset + 3;            //if less than 3 get 2
                                $offcut = 2;
                            }
                            if($offcut > $msgOffset) {
                                $msgOffset = $msgOffset + 2;            //if less than 2 get 1
                                $offcut = 1;
                            }
        
        
                            \Cache::put('msgpointer',$msgOffset,60 * 60 * 24);
                        }
        
                        if(isset($_GET['msgs']) && $_GET['msgs'] == 'newest')
                        {
                            $this->msgCounts =  \Cache::has('msgpointer') ? \Cache::get('msgpointer') : $this->msgCounts;
                            $msgOffset = $this->msgCounts + $offcut;    //get +15 messages
        
                            if($msgOffset > $messageCounts) {
                                $msgOffset = $msgOffset - 5;            //if not up to 15 get 10
                                $offcut = 10;
                            }
                            if($msgOffset > $messageCounts) {
                                $msgOffset = $msgOffset - 5;            //if not up to 10 get 5
                                $offcut = 5;
                            }
                            if($msgOffset > $messageCounts) {
                                $msgOffset = $msgOffset - 3;            //if not up to 5 get 2
                                $offcut = 2;
                            }
                            if($msgOffset > $messageCounts) {
                                $msgOffset = $msgOffset - 2;            //if not up to 2 get 1
                                $offcut = 1;
                            }
        
        
                            \Cache::put('msgpointer',$msgOffset,60 * 60 * 24);
                        }
        
        
                    // LOOP THROUGH LAST 20 MESSAGES IF THERE MORE THAN 10 MESSAGES
                    for ($i = $this->msgCounts; $i > $this->msgCounts - $offcut; $i--) 
                    { 
        
                         $header = imap_header($this->conn,$i);                             //GET HEADER INFO USING IMAP FUNCTION
                         $uid    = imap_uid($this->conn,$i);                                //GET UNIQUE MESSAGE ID FOR READING MESSAGE LATER
        
        
                         //SAVE ALL MESSAGE INFO IN ARRAY
                         $tobox    = $header->reply_to[0]->mailbox ? $header->reply_to[0]->mailbox : 'noreply';
                         $tohost   = $header->reply_to[0]->mailbox ? $header->reply_to[0]->host : 'email.com';
                         $toaddress = $tobox.'@'.$tohost;
        
        
                         $mailbox = isset($header->from[0]->mailbox) ? $header->from[0]->mailbox : 'no-reply';
                         $host    = isset($header->from[0]->host) ? $header->from[0]->host : 'email.com';
                         $fromaddress = $mailbox.'@'.$host;
        
                         $array = ['toaddress' => isset($header->toaddress) ? $header->toaddress : isset($header->to) ? $header->to[0]->mailbox.'@'.$header->to[0]->host : $toaddress,'date' => isset($header->date) ? $header->date : date('Y-m-d'),'subject' => isset($header->subject) ? $header->subject : "no subject" ,'from' => isset($header->from[0]->personal) ? $header->from[0]->personal :$fromaddress,'unseen' => isset($header->Unseen) ? $header->Unseen : 'S', 'uid' => isset($uid) ? $uid : $i,'fromemail' => $fromaddress];
                        //PASS A MESSAGE INFO INTO A MULTI ARRAY
                        $multiarray[] = $array;
        
                    }
        

        如果它很多的话,你可以将它的获取日期设置为 90 天之前。像上面一样逐块返回它。我很抱歉在那里使用了一些 laravel 辅助类,所有这些都被很好地注释掉了。 希望这对某人有帮助!

        【讨论】:

          猜你喜欢
          • 2014-05-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-26
          • 1970-01-01
          相关资源
          最近更新 更多