Search code examples
phpimap

How to read multiple lines from socket stream?


I want to retrieve email from gmails' imap server but the problem is that the responses from the server are multiple lines long (as demonstrated here) and fgets only retrieves one line.

I've tried using fgets, fread, socket_read but none of them work so either i'm using the wrong method or using the methods incorrectly. I also tried this tutorial but it didn't work either. I would appreciate if someone could help me with this.

Thanks and i'm really sorry if this is an amateur question.

Code:

<?php

$stuff = fsockopen('ssl://imap.gmail.com',993);
$reply = fgets($stuff,4096);
echo 'connection: '.$reply.'<br/>';

$request = fputs($stuff,"a1 LOGIN MyUserName Password\r\n");
$receive = socket_read($stuff, 4096);

echo 'login: '.$receive.'<br/>';


$request = fputs($stuff,"a2 EXAMINE INBOX\r\n");
$reply = '';

while(!feof($stuff))
    $reply .= fread($stuff, 4096);

echo $reply;



/*
$request = fputs($stuff,'a3 FETCH 1 BODY[]\r\n');
$reply = fgets($stuff);
echo $reply;
*/
?>

Max's answer below works. This is my implementation of it.

private function Response($instructionNumber)
{
    $end_of_response = false;

    while (!$end_of_response)
    {
        $line = fgets($this->connection,self::responseSize);
        $response .= $line.'<br/>';

        if(preg_match("/$instructionNumber (OK|NO|BAD)/", $response,$responseCode))
            $end_of_response = true;
    }

    return array('code' => $responseCode[1],
        'response'=>$response);
}

Solution

  • Generally, you know to stop reading when you get the OK/BAD/NO response for the tag you sent. If you send a1 LOGIN ... you stop when you get a1 OK/BAD/NO ....