2011-06-25 24 views
32

Necesito guardar una imagen de una url usando CURL y guardarla en una carpeta en mi servidor. He estado luchando con este código en vano. Idealmente, me gustaría tomar la imagen y guardarla como "foto1" o algo así. ¡Ayuda!Guardar imagen de url con curl PHP

function GetImageFromUrl($link) 

    { 

    $ch = curl_init(); 

    curl_setopt($ch, CURLOPT_POST, 0); 

    curl_setopt($ch,CURLOPT_URL,$link); 

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

    $result=curl_exec($ch); 

    curl_close($ch); 

    return $result; 

    } 

    $sourcecode = GetImageFromUrl($iticon); 

    $savefile = fopen(' /img/uploads/' . $iconfilename, 'w'); 
    fwrite($savefile, $sourcecode); 
    fclose($savefile); 

Respuesta

78

probar esto:

function grab_image($url,$saveto){ 
    $ch = curl_init ($url); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); 
    $raw=curl_exec($ch); 
    curl_close ($ch); 
    if(file_exists($saveto)){ 
     unlink($saveto); 
    } 
    $fp = fopen($saveto,'x'); 
    fwrite($fp, $raw); 
    fclose($fp); 
} 

y garantizar que en allow_url_fopen php.ini es permitir

+0

¡Gracias! Seguiré intentando esto y veré si eso funciona. – David

+11

Tenga en cuenta que los sitios web bien codificados buscarán un agente de usuario. ¡Cada navegador, tableta o teléfono siempre tendrá un agente de usuario! Si aún no puede obtener una imagen, probablemente debido a la detección del agente de usuario, agregue esto ... 'curl_setopt ($ ch, CURLOPT_USERAGENT, 'MyImage Collector + http: //www.yourdomainname/mybot.html'); 'o parodia de uno real' curl_setopt ($ ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: 1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); ' – bbullis

+0

¿Hay alguna limitación de tamaño de archivo al guardar una imagen como esta? ¿La limitación de carga de archivos en la configuración PHP afecta esto? – Foreever

21

Opción # 1

lugar de recoger los datos/primas binarias en una variable y luego escribir, puede usar la opción CURLOPT_FILE para mostrar directamente un archivo al curl para la descarga.

Aquí es la función:

// takes URL of image and Path for the image as parameter 
function download_image1($image_url, $image_file){ 
    $fp = fopen ($image_file, 'w+');    // open file handle 

    $ch = curl_init($image_url); 
    // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // enable if you want 
    curl_setopt($ch, CURLOPT_FILE, $fp);   // output to file 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 1000);  // some large value to allow curl to run for a long time 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); 
    // curl_setopt($ch, CURLOPT_VERBOSE, true); // Enable this line to see debug prints 
    curl_exec($ch); 

    curl_close($ch);        // closing curl handle 
    fclose($fp);         // closing file handle 
} 

Y aquí es cómo se debe llamar:

// test the download function 
download_image1("http://www.gravatar.com/avatar/10773ae6687b55736e171c038b4228d2", "local_image1.jpg"); 

Opción # 2

Ahora, Si desea descargar una archivo muy grande, esa función de arriba del caso puede no ser útil. Puede usar la función siguiente esta vez para manejar un archivo grande. Además, puede imprimir el progreso (en % o en cualquier otro formato) si lo desea. La función siguiente se implementa utilizando una función callback que escribe una porción de datos en el archivo en el progreso de la descarga.

// takes URL of image and Path for the image as parameter 
function download_image2($image_url){ 
    $ch = curl_init($image_url); 
    // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // enable if you want 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 1000);  // some large value to allow curl to run for a long time 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, "curl_callback"); 
    // curl_setopt($ch, CURLOPT_VERBOSE, true); // Enable this line to see debug prints 
    curl_exec($ch); 

    curl_close($ch);        // closing curl handle 
} 

/** callback function for curl */ 
function curl_callback($ch, $bytes){ 
    global $fp; 
    $len = fwrite($fp, $bytes); 
    // if you want, you can use any progress printing here 
    return $len; 
} 

Y aquí es cómo llamar a esta función:

// test the download function 
$image_file = "local_image2.jpg"; 
$fp = fopen ($image_file, 'w+');    // open file handle 
download_image2("http://www.gravatar.com/avatar/10773ae6687b55736e171c038b4228d2"); 
fclose($fp);         // closing file handle 
1

Versión mejorada de respuesta Komang (añadir árbitro y el agente de usuario, comprobar si se puede escribir el archivo), devolverá true si es correcto, falso si hay un error:

public function downloadImage($url,$filename){ 
    if(file_exists($filename)){ 
     @unlink($filename); 
    } 
    $fp = fopen($filename,'w'); 
    if($fp){ 
     $ch = curl_init ($url); 
     curl_setopt($ch, CURLOPT_HEADER, 0); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
     $result = parse_url($url); 
     curl_setopt($ch, CURLOPT_REFERER, $result['scheme'].'://'.$result['host']); 
     curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'); 
     $raw=curl_exec($ch); 
     curl_close ($ch); 
     if($raw){ 
      fwrite($fp, $raw); 
     } 
     fclose($fp); 
     if(!$raw){ 
      @unlink($filename); 
      return false; 
     } 
     return true; 
    } 
    return false; 
} 
+1

'CURLOPT_RETURNTRANSFER' primero lee el archivo completo a una variable php. Es más lento y puede romperse en archivos grandes. Pase el puntero del archivo con 'CURLOPT_FILE', en su lugar. – Walf

1

Este es el implemento más fácil.

function downloadFile($url, $path) 
{ 
    $newfname = $path; 
    $file = fopen($url, 'rb'); 
    if ($file) { 
     $newf = fopen($newfname, 'wb'); 
     if ($newf) { 
      while (!feof($file)) { 
       fwrite($newf, fread($file, 1024 * 8), 1024 * 8); 
      } 
     } 
    } 
    if ($file) { 
     fclose($file); 
    } 
    if ($newf) { 
     fclose($newf); 
    } 
}