PHP IMAP库 - 从邮箱中检索有限的邮件列表

时间:2010-09-29 18:47:28

标签: php email imap

我正在使用PHP内置的IMAP功能来构建一个简单的webmail客户端(主要用于访问gmail帐户)。我目前在邮箱列表视图中遇到了一个路障,我在该邮箱中显示按日期(升序或降序)排序的邮箱的分页列表。

我的初始实现使用imap_headers()检索来自邮箱的所有邮件,并根据日期对该数组进行排序,然后返回与用户想要查看的列表的当前页面对应的数组段。这适用于邮件数量较少的邮箱,但随着邮箱大小的增长,性能会大大降低(对于包含约600条邮件的邮箱,执行时间平均约为10秒)。对于这个客户端的一些用户来说,600封邮件对于一个邮箱来说是一个很小的数字,其中一些邮件很容易在他们的收件箱中有5到10万封邮件。

所以我对这个问题的第二个尝试是不是检索邮箱中所有邮件的标题,而是使用imap_num_msg()得到消息总数,并使用该数字我构造了一个for循环,其中循环计数器是用作消息编号。对于每次迭代,我用该消息号调用imap_headerinfo()。

这样做效果更好,但我的印象是消息号直接对应于收到该消息的时间,因此消息号为。 1是最早的消息,imap_num_msg()返回的数字是最新消息的消息号。所以使用它我仍然可以在我的分页列表中提供按日期排序。但经过测试后,似乎消息号与收到的日期不对应,而且我真的不知道如何分配它们。

非常感谢任何帮助或指示。

1 个答案:

答案 0 :(得分:1)

我一直在玩这个,这里有一些我正在做的事情,分页工作很好,每页只收到几封邮件。我不会粘贴所有代码,只是主要部分。希望这会有所帮助:)

// main method to get the mails __getFormattedBasics() just calls imap_hearderinfo() loop runs backwards by default to get newest first
private function __getMails($Model, $query) {
            $pagination = $this->_figurePagination($query);

            $mails = array();
            for ($i = $pagination['start']; $i > $pagination['end']; $i--) {
                $mails[] = $this->__getFormattedBasics($Model, $i);
            }

            unset($mail);

            return $mails;
        }

// this just uses the current page number, limit per page and figures the start/end for the loop above you can sort in the other direction passing asc/desc
protected function _figurePagination($query) {
            $count = $this->_mailCount($query); // total mails
            $pages = ceil($count / $query['limit']); // total pages
            $query['page'] = $query['page'] <= $pages ? $query['page'] : $pages; // dont let the page be more than available pages

            $return = array(
                'start' => $query['page'] == 1
                    ? $count    // start at the end
                    : ($pages - $query['page'] + 1) * $query['limit'], // start at the end - x pages
            );

            $return['end'] = $query['limit'] >= $count
                ? 0
                : $return['start'] - $query['limit'];

            $return['end'] = $return['end'] >= 0 ? $return['end'] : 0;

            if (isset($query['order']['date']) && $query['order']['date'] == 'asc') {
                return array(
                    'start' => $return['end'],
                    'end' => $return['start'],
                );
            }

            return $return;
        }

    private function __getFormattedBasics($Model, $message_id) {
        $mail = imap_headerinfo($this->MailServer, $message_id);
        $structure = imap_fetchstructure($this->MailServer, $mail->Msgno);

        $toName = isset($mail->to[0]->personal) ? $mail->to[0]->personal : $mail->to[0]->mailbox;
        $fromName = isset($mail->from[0]->personal) ? $mail->from[0]->personal : $mail->from[0]->mailbox;
        $replyToName = isset($mail->reply_to[0]->personal) ? $mail->reply_to[0]->personal : $mail->reply_to[0]->mailbox;

...