0

I am building my own webmail client. Like Roundcube or Squirrelmail, for example. The problem is that my version is very slow, while Roundcube is fast and I cannot understand why is that (Roundcube's source ir very big and I am unable to dive in it..)

The goal - fetch last 50 messages from mailbox. My strategy:

  1. Get number of messages in mailbox by imap_num_msg()

  2. Make array of sequence numbers from max to (max-50)

  3. For each sequence number I ran functions imap_header() and imap_fetchstructure()

It takes 10-15 seconds. It allows me to get each messages title, date, whether is has attachments or not, from, to and other information.

However, Roundcube displays the same info, but load time is only 3 seconds or so. My strategy seems to be very wrong. How can I do it faster? I'm pretty sure that it must be slow to ran imap_header and imap_fetchstructure for each sequence number, but I think there is no other way to get that information.. I'm doing something like this:

function getMessageBySequenceNumber($imapStream, $sequence_number){

    $header = imap_header($imapStream, $sequence_number);
    $structure = imap_fetchstructure($imapStream, $sequence_number);

    /* 
    ... some code parsing $structure to find out whether this emails has any attachments or not 
    */

    return [
        'uid' => imap_uid($imapStream, $i),
        'subject' => $header->subject,
        'timestamp' => $header->udate,
        'unseen' => $header->Unseen,
        'star' => $header->Flagged,
        'draft' => $header->Draft,
        'size' => $header->size,
        'has_attachments_bool' => $has_attachments_bool,
    ];
}

$imapStream = imap_open();
$first_sequence_number = imap_num_msg(); // lets imagine it returns 100
$last_sequence_number = $first_sequence_number-50;
$sequence_numbers = [100,99,88 ..., 51, 50];

$messages = [];
foreach($sequence_numbers as $sequence_number){
    $messages[] = getMessageBySequenceNumber($imapStream, $sequence_number);
}

return $messages;
user3702861
  • 747
  • 2
  • 8
  • 19
  • You gotta share some code, otherwise it's impossible to see what could trigger the pitfall. One of the things that I believe is happening is that you are loading too much data. Just load the first max 5 messages in full and then load the individual messages. – flyandi Mar 13 '15 at 19:26
  • 1
    you should be able to fetch more than one message at a time. – Max Mar 13 '15 at 20:44
  • Well - how? That's the question. imap_header() and imap_fetchstructure() seems to allow only one message at a time. – user3702861 Mar 14 '15 at 09:47

1 Answers1

0

You are fetching the messages one-by-one. This means that your PHP code has to wait for the remote IMAP server to answer you, then your PHP code is going to process the (partial) response, send the data back to the server, etc.

Use an IMAP library which allows batched operations, and read RFC 3501 to understand how to use it.

Jan Kundrát
  • 3,700
  • 1
  • 18
  • 29