views:

349

answers:

1

I'm playing around with the IMAP protocol in PHP using fsockopen to send and receive commands. My preliminary experiments work but are insanely slow. It takes about 2 minutes for the simple function below to run. I've tried several different IMAP servers and have gotten the same result. Can anyone tell me why this code is so slow?

<?php

function connectToServer($host, $port, $timeout) {
    // Connect to the server
    $conn = fsockopen($host, $port, $errno, $errstr, $timeout);

    // Write IMAP Command
    $command = "a001 CAPABILITY\r\n";

    // Send Command
    fputs($conn, $command, strlen($command));

    // Read in responses
    while (!feof($conn)) {
     $data .= fgets($conn, 1024);
    }

    // Display Responses
    print $data;

    // Close connection to server
    fclose($conn);
}

connectToServer('mail.me.com', 143, 30);

?>

This is the response I get back:

macinjosh:Desktop Josh$ php test.php
* OK [CAPABILITY mmp0613 IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS CHILDREN BINARY UNSELECT SORT LANGUAGE IDLE XSENDER X-NETSCAPE XSERVERINFO X-SUN-SORT X-SUN-IMAP X-ANNOTATEMORE X-UNAUTHENTICATE XUM1 AUTH=PLAIN STARTTLS] Messaging Multiplexor (Sun Java(tm) System Messaging Server 6.3-6.03 (built Jun  5 2008))
* CAPABILITY mmp0613 IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS CHILDREN BINARY UNSELECT SORT LANGUAGE IDLE XSENDER X-NETSCAPE XSERVERINFO X-SUN-SORT X-SUN-IMAP X-ANNOTATEMORE X-UNAUTHENTICATE XUM1 AUTH=PLAIN STARTTLS
a001 OK CAPABILITY completed
+2  A: 

It seems like feof won't return true until the remote side times out and closes the connection. The $timeout parameter that you are passing only applies to the initial connection attempt.

Try changing your while loop to print the status directly:

while (!feof($conn)) {
    print fgets($conn, 1024);
}

Or change your loop exit condition to break after its read the full reply. It would probably have to be smarter about the protocol.

Finally, I have to ask, why aren't you using PHP's built-in IMAP client?

Peter Kovacs
I want to be able do work with IMAP on servers that don't have the IMAP extension installed e.g. Shared Hosting environments.
macinjosh
Thanks, looks like that was it!
macinjosh
Such solution already exists. phpclasses.org is full of them, you can try this one: http://www.phpclasses.org/browse/package/2351.html
Havenard
yeah, I've seen all those. I just more interested in tinkering with it on my own. More for learning than anything else. Thanks though!
macinjosh