5

外部サーバーから大量のファイルをダウンロードしようとしています (約 3700 枚の画像)。これらのイメージは、それぞれ 30KB から 200KB になります。

copy()1つの画像で関数を使用すると機能します。ループで使用すると、30B の画像 (空の画像ファイル) しか取得できません。

copycURLwget、を使ってみfile_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);

何も正しく動作していないようです。残念ながら、これらすべてのファイルを一度にダウンロードする選択肢はあまりなく、できるだけ早く機能させる方法が必要です。

どうもありがとう、アントワーヌ

4

2 に答える 2

8

それらを 1 つずつ取得するのは非常に遅い場合があります。それらを 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);

私はこのアプローチを使用して、最近数百万枚の画像を取得しました。

一度に取得する画像の量は、予想されるサイズとメモリの制限によって異なります。

于 2013-03-15T16:00:09.337 に答える
6

私はそのためにこの機能を使用しましたが、かなりうまくいきました。

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

}
于 2013-03-15T15:45:54.333 に答える