2013-03-15 92 views
4

我试图从外部服务器下载大量文件(大约3700张图像)。这些图像每个从30KB到200KB。使用PHP(很多图像)从远程服务器下载多个图像

当我在1张图片上使用copy()函数时,它起作用。当我在一个循环中使用它时,我得到的只有30B图像(空图像文件)。

我试过使用copy,cURL,wgetfile_get_contents。每次我都会得到很多空文件,或者根本没有。

这里是我试过的代码:

wget的:

exec('wget http://mediaserver.centris.ca/media.ashx?id=ADD4B9DD110633DDDB2C5A2D10&t=pi&f=I -O SIA/8605283.jpg'); 

副本:

if(copy($donnees['PhotoURL'], $filetocheck)) { 
    echo 'Photo '.$filetocheck.' updated<br/>'; 
} 

卷曲:

$ch = curl_init(); 
$source = $data[PhotoURL]; 
curl_setopt($ch, CURLOPT_URL, $source); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$data = curl_exec ($ch); 
curl_close ($ch); 

$destination = $newfile; 
$file = fopen($destination, "w+"); 
fputs($file, $data); 
fclose($file); 

一切似乎正常工作。不幸的是,我没有太多的选择一次下载所有这些文件,我需要一种方法使其尽快发挥作用。

非常感谢,安托万

+0

他们可能会阻止像这样的大规模下载。尝试询问服务器/服务的管理员。 – Sammitch 2013-03-15 15:40:44

+0

这可能是有道理的,但这台服务器是这样的大规模下载,这是一个系统,我已经去自己的图像,而不是他们通过FTP发送给我。 – 2013-03-15 20:23:06

回答

5

我用这个函数,工作得很好。

function saveImage($urlImage, $title){ 

    $fullpath = '../destination/'.$title; 
    $ch = curl_init ($urlImage); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); 
    $rawdata=curl_exec($ch); 
    curl_close ($ch); 
    if(file_exists($fullpath)){ 
     unlink($fullpath); 
    } 
    $fp = fopen($fullpath,'x'); 
    $r = fwrite($fp, $rawdata); 

    setMemoryLimit($fullpath); 

    fclose($fp); 

    return $r; 
} 

与此另一种防止内存溢出组合:

function setMemoryLimit($filename){ 
    set_time_limit(50); 
    $maxMemoryUsage = 258; 
    $width = 0; 
    $height = 0; 
    $size = ini_get('memory_limit'); 

    list($width, $height) = getimagesize($filename); 
    $size = $size + floor(($width * $height * 4 * 1.5 + 1048576)/1048576); 

    if ($size > $maxMemoryUsage) $size = $maxMemoryUsage; 

    ini_set('memory_limit',$size.'M'); 

} 
+0

一开始没有工作,但似乎现在工作。在变量“fullpath”中,我使用了“/ home/mls/public_html ...”,这显然是错误的。非常感谢,我现在可以下载图片了,谢谢! – 2013-03-15 21:19:09

+0

欢迎您:)祝你好运! – Alvaro 2013-03-18 10:40:35

9

让他们一个一个可能相当缓慢。考虑将它们分成20-50个图像的包并用多个线程抓取它们。下面的代码让你开始:

$chs = array(); 
$cmh = curl_multi_init(); 
for ($t = 0; $t < $tc; $t++) 
{ 
    $chs[$t] = curl_init(); 
    curl_setopt($chs[$t], CURLOPT_URL, $targets[$t]); 
    curl_setopt($chs[$t], CURLOPT_RETURNTRANSFER, 1); 
    curl_multi_add_handle($cmh, $chs[$t]);  
} 

$running=null; 
do { 
    curl_multi_exec($cmh, $running); 
} while ($running > 0); 

for ($t = 0; $t < $tc; $t++) 
{ 
    $path_to_file = 'your logic for file path'; 
    file_put_contents($path_to_file, curl_multi_getcontent($chs[$t])); 
    curl_multi_remove_handle($cmh, $chs[$t]); 
    curl_close($chs[$t]); 
} 
curl_multi_close($cmh); 

我用这种方法来获取一些百万计的图像最近,因为一个接一个将采取长达一个月。

一次抓取的图像数量应该取决于它们的预期大小和内存限制。