PHP cURL download progress using jquery PHP cURL download progress using jquery curl curl

PHP cURL download progress using jquery


with that method, you'll run in to all kind of caching problems, is php output buffering? you'll have a problem. are you behind a web server, ala nginx/apache/lighthttp/anything? you'll have a problem. is the browser cacheing output? (all mainstream browsers do), you'll have a problem.

i suggest an alternative which will have none of those problems: using $_SESSION to store download percentage, and querying the percentage with XMLHttpRequests (actually querying the percentage over WebSockets would be optimal, lagless, use less bw, etc, but much harder to implement)

downloadmovie.php

<?php require_once(dirname(__FILE__)."/functions.php");$url = $_POST['source'];$headers = getHeaders($url);$url = $headers['url'];//after validation of inputsession_start();$_SESSION['download_percentage']=0.0;//initialize itsession_write_close();fastcgi_finish_request();//or if you're not using fcgi, some equivalent..$path = dirname(__FILE__)."/temp/test.mp4";$fp = fopen ($path, 'w+');$ch = curl_init();curl_setopt( $ch, CURLOPT_URL, $url );curl_setopt( $ch, CURLOPT_RETURNTRANSFER, false );curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progress' );curl_setopt( $ch, CURLOPT_NOPROGRESS, false );curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 100 );curl_setopt( $ch, CURLOPT_FILE, $fp );curl_exec( $ch );curl_close( $ch );fclose( $fp );function progress($resource,$download_size, $downloaded, $upload_size, $uploaded){    $percentage=$download_size==0? 0.0 : (($downloaded/$download_size)*100);    session_start();    $_SESSION['download_percentage']=$percentage;    session_write_close();}

getProgress.xhr.php

<?php if(""===session_id()){session_start();}echo $_SESSION['download_percentage']??'?';

then monitoring the progress in the browser:

(function checkProgress() {    "use strict";    var xhr = new XMLHttpRequest();    xhr.open("GET", "getProgress.xhr.php");    xhr.addEventListener("readystatechange", function(ev) {        var xhr = ev.target;        if (xhr.readyState !== 4) {            return;        }        console.log(xhr.responseText + " percent downloaded!");        if (xhr.responseText === "100") {            return; /*stop checking for progress when its finished*/        }        setTimeout(checkProgress, 1000); //<<check for progress every 1 second    });    xhr.send();})();

important edit: as @drew010 pointed out, it won't work without session_write_close();session_start(); each time curl updates the value, fixed that.


Quote from cURL download progress in PHP

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 workcurl_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();?>


Don't use ob_flush(), just flush().(Remove all the ob_ functions).Also, consider modifying the buffersize:

curl_setopt($ch, CURLOPT_BUFFERSIZE, 16000);

Experiment with the size.