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 限制返回的消息数的主要内容,如果未能解决你的问题,请参考以下文章