Прогресс загрузки cURL в PHP

Я довольно новичок в cURL, поэтому я боролся с этим часами. Я пытаюсь загрузить источник веб-сайта в iframe, используя cURL, и пока он загружается, чтобы показать, сколько из него загружено. До сих пор я успешно загрузил источник, не показывая ход загрузки. Можете ли вы объяснить, как показать ход загрузки? Без cURL я бы прочитал байт файла байтом и разделил общее количество загруженных байтов на общий размер файла. Как это можно сделать в cURL, так как он читает источник в целом? (по крайней мере, я думаю, что это единственный способ, не уверен) Вот что у меня есть до сих пор:

/* Download source */ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $adress); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); $html = curl_exec($ch); curl_close($ch); 

Solutions Collecting From Web of "Прогресс загрузки cURL в PHP"

Что вам нужно

 <?php ob_start(); echo "<pre>"; echo "Loading ..."; ob_flush(); flush(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://stackoverflow.com"); //curl_setopt($ch, CURLOPT_BUFFERSIZE,128); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress'); curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); $html = curl_exec($ch); curl_close($ch); function progress($resource,$download_size, $downloaded, $upload_size, $uploaded) { if($download_size > 0) echo $downloaded / $download_size * 100; ob_flush(); flush(); sleep(1); // just to see effect } echo "Done"; ob_flush(); flush(); ?> 

Вот как обратный вызов выглядит в C:

 typedef int (*curl_progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); 

Вероятно, в PHP это должно выглядеть

 curl_progress_callback($clientp, $dltotal, $dlnow, $ultotal, $ulnow) 

Итак, предположим, что у вас есть page.html, который загружает .php-файл в iframe.

В вашем скрипте php вам понадобятся следующие функции:

 curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curl_progress_callback'); curl_setopt($curl, CURLOPT_BUFFERSIZE,64000); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); 

который должен произвести выход, подобный следующему:

 0 0.1 0.2 0.2 0.3 0.4 ... 

то на странице iframe у вас будет индикатор выполнения

 <div id="progress-bar"> <div id="progress">0%</div> </div> 

CSS будет что-то вроде этого

 #progress-bar { width: 200px; padding: 2px; border: 2px solid #aaa; background: #fff; } #progress { background: #000; color: #fff; overflow: hidden; white-space: nowrap; padding: 5px 0; text-indent: 5px; width: 0%; } 

Javascript

 var progressElement = document.getElementById('progress') function updateProgress(percentage) { progressElement.style.width = percentage + '%'; progressElement.innerHTML = percentage + '%'; } 

Вы можете загрузить его на JavaScript и обновить индикатор выполнения, например:

 <script>updateProgress(0);</script> <script>updateProgress(0.1);</script> <script>updateProgress(0.2);</script> 

Вам может быть интересен еще один пример кода

Чтобы использовать обратный вызов внутри класса, вы должны сделать это следующим образом:

 curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this, 'progress')); 

или при использовании статических функций, например:

 curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array('self', 'progress')); 

… для функции обратного вызова, чтобы сделать все, что вам нужно:

 private static function progress($resource, $downloadSize, $downloaded, $uploadSize, $uploaded) { // emit the progress Cache::put('download_status', [ 'resource' => $resource, 'download_size' => $downloadSize, 'downloaded' => $downloaded, 'upload_size' => $uploadSize, 'uploaded' => $uploaded ], 10); }