Я пытаюсь загрузить много файлов с внешнего сервера (около 3700 изображений). Эти изображения идут от 30 КБ до 200 КБ каждый.
Когда я использую функцию copy()
на 1 изображении, он работает. Когда я использую его в цикле, все, что я получаю, это 30B изображений (пустые файлы изображений).
Я попытался использовать copy
, cURL
, wget
и 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);
Кажется, что ничего не работает. К сожалению, у меня нет большого выбора для загрузки всех этих файлов сразу, и мне нужен способ заставить его работать как можно скорее.
Большое спасибо, Антуан
Я использовал эту функцию для этого и работал очень хорошо.
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'); }
Получение их один за другим может быть довольно медленным. Подумайте о том, чтобы разбить их на пакеты с 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);
Я использовал этот подход, чтобы захватить несколько миллионов изображений в последнее время, поскольку один за другим займет до месяца.
Количество снимков, которые вы захватываете сразу, должно зависеть от их ожидаемого размера и пределов памяти.