imap_search 限制返回的消息数

Posted

技术标签:

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

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

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

有没有办法做到这一点?

谢谢。

【问题讨论】:

【参考方案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 辅助类,所有这些都被很好地注释掉了。 希望这对某人有帮助!

【讨论】:

以上是关于imap_search 限制返回的消息数的主要内容,如果未能解决你的问题,请参考以下文章

如何设置servlet中并发请求数的限制?

微信公众平台图文消息条数限制在1条以内

微信公众平台图文消息条数限制在1条以内

微信公众平台图文消息条数限制在1条以内

移动云消息队列RabbitMQ对资源创建数量有限制吗?

有没有办法限制客户端在 Python 聊天室应用程序中发送的消息数/秒?