jeudi 17 novembre 2011

Plus rapide que file_get_contents : optez pour cURL !


Lors de la réalisation et mise au point de robots en PHP (bot crawlers notamment), je me suis aperçu que les durées d'exécution du script étaient énormes. Il s'agissait en fait de la fonction file_get_contents() qui met énormément de temps à se connecter/restituer le résultat de la page appelée.

Afin de résoudre le problème, il existe une librairie appelée libcurl contenant une extension : cURL. Cette extension *magique* est 2 à 3 fois plus rapide que les file_get_contents() et fopen() et beaucoup plus facile à utiliser que les fonctions de socket PHP.

Comment l'utiliser ?

Voici un exemple de fonction PHP :
<?php

function curl_http_request(
    $url = 'www.domain.com/index.php',         /* Target URL */
    $getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $filesdata = array(),       /* HTTP FILES Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $cookie = array()         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    ) {

    $curlopt = array();
    $cookie_str = '';
    $getdata_str = count($getdata) ? '?' : '';

    foreach ($getdata as $k => $v) $getdata_str .= (strlen($getdata_str)>0?'&':'').urlencode($k).'='.urlencode($v);

   //assignation uploads en POST : _POST['champ']=filetmpname et _POST['champ_real']=filename
    foreach ($filesdata as $k => $v) {
        if ( $filesdata[$k]['error'] == UPLOAD_ERR_OK ) {
            $postdata[$k]='@'.$filesdata[$k]['tmp_name'];
            $postdata[$k."_real"]=$filesdata[$k]['name'];
        }
    }
   
    foreach ($cookie as $k => $v) $cookie_str .= (strlen($cookie_str)>0?'; ':'').urlencode($k).'='.urlencode($v);

    if ( count($postdata) ) {
        $curlopt = array (
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $postdata
        );
    }

    $default_curlopt = array(
    CURLOPT_TIMEOUT => 2, //timeout 2sec
    CURLOPT_FAILONERROR => 1, //si page error, on ne d/l pas
    CURLOPT_RETURNTRANSFER => 1, //return le transfert as a string
    CURLOPT_FOLLOWLOCATION => 1, //on follow si redirection header desactive par défaut
    CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT']?$_SERVER['HTTP_USER_AGENT']:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 AlexaToolbar/alxf-1.54 Firefox/3.6.13 GTB7.1"
    );
    $curlopt = array(CURLOPT_URL => $url.$getdata_str) + $curlopt + $default_curlopt;
   
   
    // Création d'une nouvelle ressource cURL
    $ch = curl_init();
   
    // Configuration de l'URL et d'autres options
    curl_setopt_array($ch, $curlopt);
   
    //Envoi des données
    $results_returned = curl_exec($ch);
    if ( $results_returned === false ) trigger_error(curl_error($ch));

    // Fermeture de la session cURL
    curl_close($ch);
   
    return $results_returned;
}

//exemple: fishing du fichier test.php, utilisant tous les paramètres de formulaire
echo curl_http_request("www.domain.com/test.php",$_GET,$_POST, $_FILES, $_COOKIE);
?>

Facile, accessible et supporte de nombreux protocoles.

Aucun commentaire:

Enregistrer un commentaire