2010-08-15 7 views
7

Korzystanie poniższy kod każdego pobrania obrazu) file_get_contents()) trwa przeciętnie 8-15 sekund .....file_get_contents() z kontekstu użyć http/1.1 znacząco powolny prędkość pobierania

Jeśli nie używam kontekst na file_get_contents(), a następnie pobieranie obrazu zajmuje mniej niż sekundę.

Jeśli zmienię $ opts na poniżej, otrzymam taką samą wydajność jak file_get_contents() bez kontekstu, który zajmuje 13 sekund, aby przetworzyć 2500 obrazówx.

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

reprodukować:

$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 />'); 

Odpowiedz

9

Żądania HTTP 1.1 są domyślnie potokowane. Jeśli nie "Connection: Close", zakłada "Połączenie: Keep-Alive", a następnie musisz poczekać aż upłynie limit czasu połączenia (ponieważ nigdy go nie zamknąłeś) przed rozpoczęciem kolejnej pętli.

+0

Dziękujemy! Wnioski, które pobierały 0,15 s na HTTP 1.0, trwały co najmniej 5 sekund w protokole HTTP 1.1. Prosty 'header (" Connection: close "); naprawione! – Mave

0

context mówi file_get_contents(), aby zamknąć połączenie HTTP za każdym razem. Być może dlatego kod ten trwa tak długo, ponieważ wielokrotnie zamyka i ponownie otwiera połączenia? Nie jestem zaznajomiony z internals z file_get_contents(), ale możesz być w stanie dostosować kontekst, aby użyć "Connection: keep-alive" dla wszystkich z wyjątkiem ostatniego połączenia i "Connection: close" dla ostatniego połączenia.

+1

Spodziewam się, że 'file_get_contents()' będzie zamykał swoje połączenie niezależnie - zamyka pliki uchwytów podczas odczytu plików z dysku. Jeśli chcesz wydajności, cURL to lepszy zakład. Możesz po prostu wielokrotnie używać tego samego uchwytu do curl; połączenie jest domyślnie otwarte, jeśli dobrze pamiętam. –

+0

Zgadzam się z tobą na temat korzystania z cURL, chyba że istnieje powód, dla którego dorgan musi użyć file_get_contents(). –