PHP中使用ddeboer/imap调用$mailbox->getMessages()筛选高于指定UID的邮件
实现方案
ddeboer/imap 库的 $mailbox->getMessages() 方法支持传入搜索条件,你可以通过构造UID相关的搜索规则实现增量拉取,完全符合你提到的IMAP标准流程,具体实现如下:
前置准备
你需要在本地持久化存储两个字段:
- 上次拉取时邮箱的 uidvalidity 值
- 上次拉取到的邮件最高UID值
代码实现
// 读取本地存储的历史记录 $lastSavedUidValidity = 本地存储的历史uidvalidity; $lastSavedMaxUid = 本地存储的历史最高邮件UID; // 获取当前邮箱的最新uidvalidity $currentUidValidity = $mailbox->getUidValidity(); $search = new \Ddeboer\Imap\SearchExpression(); if ($currentUidValidity === $lastSavedUidValidity) { // uidvalidity无变更,增量拉取UID大于历史最高值的新邮件 $search->addCondition(new \Ddeboer\Imap\Search\Uid\UidGreaterThan($lastSavedMaxUid)); $messages = $mailbox->getMessages($search); } else { // uidvalidity变更,全量拉取所有邮件 $messages = $mailbox->getMessages(); // 更新本地存储的uidvalidity为最新值 你的自定义存储方法($currentUidValidity); } // 拉取完成后,更新本地存储的最高UID $messageArr = iterator_to_array($messages); if (!empty($messageArr)) { $currentMaxUid = max(array_map(fn($msg) => $msg->getId(), $messageArr)); 你的自定义存储方法($currentMaxUid); }
版本兼容说明
如果你使用的库版本较低,找不到UidGreaterThan类,可以直接传入原生IMAP搜索字符串实现相同效果:
// 低版本兼容写法 $messages = $mailbox->getMessages("UID {$lastSavedMaxUid}:*");
注意事项
- 调用
$message->getId()获取到的就是邮件的唯一UID,不要和临时的消息序列号混淆 - 拉取邮件过程中如果出现异常,不要更新本地存储的uidvalidity和最高UID,避免遗漏邮件
内容的提问来源于stack exchange,提问作者Benedikt
相关产品推荐
相关产品推荐

