Search code examples
phpimap

PHP IMAP connection speed


this is my first experimentations with imap in php.

I am making a panel for my company, where I upload the clientes, with name and email, and asignit to users,

so when an user enters the panel and have a client there, the panel check the user email account and search for emails from the client email,

my problem is that the first time I load the panel it gets very slow, it takes 5 sec to 15 secs to load (or more sometimes) but after the first load, it is fast, but if I go away for let's say 10 minutes and reload the panel it gets slow again for the first time.

this is my code; for each user in the panel I call this function:

function mostrarCorreosRelacionados($remitente){
$hostname = '{localhost:143}INBOX';
$correo = explode("|||",$_SESSION['correo']);
$username = $correo[0];
$password = $correo[1];

/* Intento de conexión */
$inbox = imap_open($hostname,$username,$password) or die('No se pudo conectar con: usuario: '.$username.' y clave: '.$password.' ' . imap_last_error());

/* Recuperamos los emails */
$emails = imap_search($inbox,'FROM "'.$remitente.'"');


/* Si obtenemos los emails, accedemos uno a uno... */
if($emails) {

    /* variable de salida */
    $output = '';

    /* Colocamos los nuevos emails arriba */
    rsort($emails);

    /* por cada email... */
    $ii=0;
    foreach($emails as $email_number) {

        /* Obtenemos la información específica para este email */
        $overview = imap_fetch_overview($inbox,$email_number,0);
        //$body = imap_fetchbody($inbox,$email_number,4);

        $uid = imap_uid($inbox, $email_number);

        $header = imap_header($inbox,$email_number);
        $fromInfo = $header->from[0];
        $replyInfo = $header->reply_to[0];


        $details = array(
            "fromAddr" => (isset($fromInfo->mailbox) && isset($fromInfo->host))
                ? $fromInfo->mailbox . "@" . $fromInfo->host : "",
            "fromName" => (isset($fromInfo->personal))
                ? $fromInfo->personal : "",
            "replyAddr" => (isset($replyInfo->mailbox) && isset($replyInfo->host))
                ? $replyInfo->mailbox . "@" . $replyInfo->host : "",
            "replyName" => (isset($replyTo->personal))
                ? $replyto->personal : "",
            "subject" => (isset($header->subject))
                ? $header->subject : "",
            "udate" => (isset($header->udate))
                ? $header->udate : ""
        );

        //$message = mail_mime_to_array($inbox,$email_number);



        /* Mostramos la información de la cabecera del email */

        $output.= '<li>';

        $output.= '<div class="encabezadoMail '.($overview[0]->seen ? 'read' : 'unread').'">';

        $output.= '<span class="subject">Asunto: '.decodificarTexto($details["subject"]).'</span><br />';

        $output.= '<a href="mailto:'.$fromInfo->mailbox.'@'.$fromInfo->host.'" class="from" title="'.$fromInfo->mailbox.'@'.$fromInfo->host.'">'.decodificarTexto($fromInfo->personal).'</a><br />';

        $output.= '<span class="textoChico">'.$overview[0]->date.'</span>';

        $output.= '</div>';



        /* Mostramos el mensaje del email */

        $output.= '<div class="cuerpoMail" id="msg_'.$i.'" style="display:none;">'.utf8_encode(getBody($uid,$inbox)).'</div>';

        $output.= '</li>';




        $ii++;
    }



    print '<ul class="emails"><li class="encabezadoMail"><strong>E-mails</strong></li>'.$output.'</ul>';

} 



/* Cerramos la connexión */

imap_close($inbox);
}

in the imap_open I have tried localhost, domain and ip, but all seems to work the same.

any ideas???

UPDATE TO MONKEYZEUS

I did what you told me and here is what I got:

FIST CLIENT

conexión: 0.0309870243073 seconds Recuperamos: 26.7151398659 seconds

SECOND CLIENT

conexión: 0.102792978287 seconds Recuperamos: 0.0511429309845 seconds

THIRD CLIENT

conexión: 0.00676202774048 seconds Recuperamos: 0.0503911972046 seconds

it just happens in the first time, and if I press F5 the long time I got on the first client does not happends, it load fast as the others, if I wait 10 minutes it gets slow again in the first client


Solution

  • You will have to figure out what is taking the longest.

    I will guess it is this part:

    /* Intento de conexión */
    $inbox = imap_open($hostname,$username,$password) or die('No se pudo conectar con: usuario: '.$username.' y clave: '.$password.' ' . imap_last_error());
    
    /* Recuperamos los emails */
    $emails = imap_search($inbox,'FROM "'.$remitente.'"');
    

    So try benchmarking it:

    $start = microtime(true); // start timer
    
    /* Intento de conexión */
    $inbox = imap_open($hostname,$username,$password) or die('No se pudo conectar con: usuario: '.$username.' y clave: '.$password.' ' . imap_last_error());
    
    echo 'conexión: '.(microtime(true)-$start).' seconds<br>'; // show results
    
    // ---------------------------------------------------------------------
    
    $start = microtime(true); // start timer again
    
    /* Recuperamos los emails */
    $emails = imap_search($inbox,'FROM "'.$remitente.'"');
    
    echo 'Recuperamos: '.(microtime(true)-$start).' seconds<br>'; // show new results
    

    conexión is probably the slowest part. This could be because of your mail server.

    UPDATE

    According to your benchmarks it is clear that imap_search() is the slowest part.

    This is because it is performing a database search and you have these possible issues:

    • Your mail server's hardware is very weak
    • Your mail server has 100's of gigabytes of data/email so the query naturally slows down
    • You are running out of hard drive space on the mail server

    The reason it goes fast the second time is because databases perform something called caching so the results of the query were loaded into memory (RAM) but after 10 minutes that cache is either cleared by the database or a change occurred to the data so the query needs to be re-cached.