2010-08-15 13 views
7

usando il codice seguente ogni download di immagini) file_get_contents()) prende in media 8-15 secondi .....file_get_contents() con il contesto di utilizzare http/1.1 significativamente lenta velocità di download

Se io non uso un contesto su file_get_contents(), quindi il download dell'immagine è inferiore a un secondo.

Se cambio l'opzione $ in, di seguito ottengo le stesse prestazioni di file_get_contents() senza un contesto che richiede appox 13 secondi per elaborare 2.500 immaginix.

$opts = array(
    'http'=>array(
     'protocol_version'=>'1.1', 
     'method'=>'GET', 
     'header'=>array(
      'Connection: close' 
     ), 
     'user_agent'=>'Image Resizer' 
    ) 
); 

Riprodurre:

$start_time = mktime(); 
$products = array(
     array('code'=>'A123', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A124', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A125', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A126', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A127', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A128', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A134', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A135', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A146', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png'), 
     array('code'=>'A165', 'image_url'=>'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png') 
    ); 

    if (count($products) > 0) { 
     $opts = array(
      'http'=>array(
       'protocol_version'=>'1.1', 
       'method'=>'GET', 
       'user_agent'=>'Image Resizer' 
      ) 
     ); 
     $context = stream_context_create($opts); 
     $def_width = 100; 
     $max_width = $def_width; 
     foreach($products as $product) { 
      $code = $product['code']; 
      $folder = substr($code, 0, 3); 
      echo('Looking at: ' .$product['code'] ."<br />"); 
      $file = '/tmp/' .$folder .'/' .$code .'_' .$def_width .'.jpg'; 
      $filemtime = @filemtime($file); 
      $gen_file = true; 
      if ($filemtime !== false) { 
       $file_age = (time() - $filemtime); 
       if ($file_age <= 300) { 
        $gen_file = false; 
       } 
      } 
      echo('&nbsp;&nbsp;&nbsp;&nbsp;File not cached or cached file has expired<br />'); 
      if ($gen_file) { 
       echo('&nbsp;&nbsp;&nbsp;&nbsp;Getting File...'); 
       $imgStr = file_get_contents($product['image_url'], false, $context); 
       $img = @imagecreatefromstring($imgStr); 
       if (is_resource($img)) { 
        echo('DONE' .'<br />'); 
        $image_x = imagesx($img); 
        $image_y = imagesy($img); 
        if ($def_width >= $image_x) { 
         $def_width = $image_x; 
        } 
        echo('&nbsp;&nbsp;&nbsp;&nbsp;Calculating Scale<br />'); 
        $ts = min($max_width/$image_x,$max_width/$image_y); 
        $thumbhght = $ts * $image_y; 
        $thumbwth = $ts * $image_x; 

        $thumb_image_resized = imagecreatetruecolor($thumbwth, $thumbhght); 
        imagecopyresampled($thumb_image_resized, $img, 0, 0, 0, 0, $thumbwth, $thumbhght, $image_x, $image_y); 
        echo('&nbsp;&nbsp;&nbsp;&nbsp;Checking For Directory<br />'); 
        if (!is_dir('/tmp/' .$folder)) { 
         mkdir('/tmp/' .$folder); 
        } 
        echo('&nbsp;&nbsp;&nbsp;&nbsp;Writing File<br />'); 
        $new_file = '/tmp/' .$folder .'/' .$code .'_' .$def_width .'.jpg'; 

        imagejpeg($thumb_image_resized, $new_file, 100); 
        echo('&nbsp;&nbsp;&nbsp;&nbsp;DONE<br />'); 

        imagedestroy($img); 
        imagedestroy($thumb_image_resized); 
       } else { 
        echo('Problem Getting Image<br />'); 
        die(); 
       } 
      } else { 
       echo('&nbsp;&nbsp;&nbsp;&nbsp;Already Exists<br />'); 
      } 
     } 
    } 
    $end_time = mktime(); 
    echo('Completed In...' .($end_time - $start_time) .' seconds(s)<br />'); 

risposta

9

Le richieste HTTP 1.1 sono pipeline di default. Se non si esegue il "Connection: Close", si presuppone "Connection: Keep-Alive" e quindi si deve attendere il timeout della connessione (poiché non è mai stato chiuso in modo esplicito) prima dell'avvio del ciclo successivo.

+0

Grazie! Le richieste che richiedevano 0.15 su HTTP 1.0 richiedevano almeno 5 secondi su HTTP 1.1. Un semplice header '(" Connection: close "); aggiustato! – Mave

0

vostro contesto dice file_get_contents() per chiudere la connessione HTTP ogni volta. Forse è per questo che il codice impiega così tanto tempo, poiché chiude e riapre le connessioni molte volte? Non ho familiarità con i componenti interni di file_get_contents(), ma potresti essere in grado di modificare il contesto per utilizzare "Connessione: keep-alive" per tutti tranne l'ultima connessione e "Connessione: chiusa" per l'ultima.

+1

Mi aspetto che 'file_get_contents()' chiuda la sua connessione a prescindere - chiude gli handle di file durante la lettura dei file dal disco. Se vuoi prestazioni, cURL è una scommessa migliore. Puoi semplicemente riutilizzare più volte la stessa maniglia del ricciolo; la connessione viene mantenuta aperta di default, se ricordo correttamente. –

+0

Sono d'accordo con te sull'uso di cURL, a meno che non ci sia un motivo per cui dorgan deve usare file_get_contents(). –