3

I'm using cURL to upload a file via given URL. (user gives URL, and my server downloads the file)

For a progressbar, I use the CURLOPT_PROGRESSFUNCTION option. I want the function of the progress to also calculate the speed of download, and how much time left.

$fp = fopen($temp_file, "w");
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOPROGRESS, false );
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, "curl_progress_callback");
curl_setopt($ch, CURLOPT_FILE, $fp);
$success = curl_exec($ch);
$curl_info = curl_getinfo($ch);
curl_close($ch);
fclose($fp);

function curl_progress_callback ($download_size, $downloaded_size, $upload_size, $uploaded_size) {
    global $fileinfo;
    if (!$downloaded_size) {
        if (!isset($fileinfo->size)) {
            $fileinfo->size = $download_size;
            event_callback(array("send" => $fileinfo));
        }
    }
    event_callback(array("progress" => array("loaded" => $downloaded_size, "total" => $download_size)));
}

Thank you! and sorry for my English

HTMHell
  • 4,572
  • 4
  • 30
  • 70
  • http://stackoverflow.com/questions/1939029/curl-download-progress-in-php-not-working – Carsten Hellweg Apr 10 '14 at 09:21
  • @CarstenHellweg I don't think you understand my question. The callback function is working fine. What I want is to calculate the speed of the downloading of file to the server, and hoe much time left for the download. – HTMHell Apr 10 '14 at 09:30

1 Answers1

5

Add this before curl_exec:

$startTime = $prevTime = microtime(true);
$prevSize = 0;

You can calculate the average and current speed, and remaining time by adding this to the callback function:

$averageSpeed = $downloaded_size / (microtime(true) - $startTime);

$currentSpeed = ($downloaded_size - $prevSize) / (microtime(true) - $prevTime);
$prevTime = microtime(true);
$prevSize = $downloaded_size;

$timeRemaining = ($downloaded_size - $download_size) / $averageSpeed;

Speed is measured in Bytes/s and remaining time in seconds.

RVF
  • 66
  • 3
  • It tells me `PHP Warning: Division by zero` on this line: `$currentSpeed = ($downloaded_size - $prevSize) / (time() - $prevTime);` – HTMHell Apr 15 '14 at 20:32
  • @ArielAharonson Hmm, I should've checked the code better. Please check the updated answer. – RVF Apr 15 '14 at 21:19
  • Thanks! it works now. BTW: is it possible to reduce the times that the function `curl_progress_callback` is running? For example, if the function is running 100 times in a second, is it possible to make it 50? – HTMHell Apr 16 '14 at 10:16
  • @ArielAharonson You might be able to do that by changing `CURLOPT_BUFFERSIZE` to a higher value using `curl_setopt`. – RVF Apr 16 '14 at 15:50
  • Will it effect anything else, or only the function repeat rate? – HTMHell Apr 17 '14 at 06:31
  • @ArielAharonson There doesn't seem to be much information on what `CURLOPT_BUFFERSIZE` actually affects, but it seems that it only affects how frequently the callbacks are called. It might also affect the amount of bytes CURL downloads before writing to the disk. – RVF Apr 17 '14 at 12:11