7

我正在尝试将多个邮箱导出到数据库。我当前的脚本将连接 IMAP 并循环所有消息。尽管对于较大的邮箱,这将不起作用,并且会减慢甚至停止。

这个想法是每天运行脚本以将所有尚未在数据库中的消息“复制”到数据库中。获取大量电子邮件的最佳方式是什么(20k 封邮件分布在大约 40 - 50 个文件夹中)。

最终,这将需要在单个服务器上每天扫描数百甚至数千个帐户(所以想象一下数据量)。它将邮件(uid 和主题)存储到数据库中,并创建一个将存储在数据服务器上的包(因此它还需要获取附件)。

4

2 回答 2

6

因此,您想通过 IMAP 执行电子邮件备份。有专业的软件工具可以做到这一点。

让我们从简单的事情开始:从收件箱文件夹中为特定用户下载一封电子邮件。这需要您 (a) 使用用户的凭据登录,(b) 选择收件箱文件夹,以及 (c) 下载消息(假设您已经知道它的 UID,即 55)。您在 IMAP 中按如下方式执行此操作(仅限请求 - 未显示响应):

01 LOGIN username password
02 SELECT INBOX
03 UID FETCH 55 BODY[]

特定文件夹中的每条消息都有一个UID这是永远不会更改的邮件的唯一标识符 -该文件夹中的任何其他邮件都不能使用它。新消息的 UID 必须高于以前的消息。这使它成为确定您之前是否已经下载过该消息的有用工具。

下一步:现在让我们看看在收件箱文件夹中下载所有新邮件。假设您是第一次下载消息,并且收件箱当前有 UID 为 54、55 和 57 的消息。您可以使用以下命令一次下载这些消息:

03 UID FETCH 54,55,57 BODY[]

(如果有很多要下载的内容,您可能希望将其分批(例如一次 30 个)分解。)完成此操作后,您将存储迄今为止下载的最高 UID。下次,您可以检查是否有高于该值的 UID,如下所示:

04 UID FETCH 58:* UID

这将检索 UID(仅)用于 UID 从 58 开始的消息。如果得到结果,则下载这些结果,然后再次存储 UID。等等。

有一个问题。只要文件夹的 UIDVALIDITY 属性(包括在对 SELECT 命令的响应中)不更改,消息的 UID 就有效。如果由于某种原因发生更改,该文件夹将失效,您需要重新下载该文件夹中的所有邮件。

最后,您希望将此扩展为适用于所有用户的所有文件夹。为了获取特定用户的所有文件夹,您可以使用 IMAP LIST 命令:

05 LIST "" "*"

您需要事先知道用户的凭据并遍历它们。

这是您需要做的事情背后的 IMAP 理论。在 PHP 中实现它留作练习。

于 2013-03-04T19:48:39.923 回答
2

你在用imap_ping吗?

imap_ping() ping 流以查看它是否仍然处于活动状态。它可能会发现新邮件;这是定期“新邮件检查”的首选方法,也是具有不活动超时的服务器的“保持活动状态”的首选方法。

其他要看的:imap_timeout imap_reopen

事实上有一种方法叫做reopen建议不是这样的:)

如果您似乎无法保持连接,另一个选择是导出数据以mbox格式化并在本地获取。对于大型邮箱可能会更快,并且可以消除超时/连接问题。

于 2013-03-01T20:31:16.990 回答