Skip to content

Instantly share code, notes, and snippets.

@stuudmuffin
Forked from bdunogier/curl_progress.php
Last active May 11, 2024 20:21
Show Gist options
  • Save stuudmuffin/104fe2f24b3c3d02b21e1fb3d61eeb6a to your computer and use it in GitHub Desktop.
Save stuudmuffin/104fe2f24b3c3d02b21e1fb3d61eeb6a to your computer and use it in GitHub Desktop.
PHP/cURL download progress monitoring
<?php
//If output buffer flushing does not work, web-search for reasons your php/webserver setup may need to be adjusted
header('X-Accel-Buffering: no');
if (ob_get_level() == 0) ob_start();
//create javascript progress bar
echo "<html>
<head>
<script type='text/javascript'>
function updateProgress(perc) {
document.getElementById('info').innerHTML = perc + '%';
document.getElementById('prog').value = perc;
}
</script>
</head>
<body>
<p>Lets see some progress</p>
<progress id='prog' value='0' max='100.0'></progress> <span id='info'>0%</span>
";
//flush the progress bar
ob_flush();
flush();
//Callback Function for later
function progressCallback( $resource, $download_size, $downloaded_size, $upload_size, $uploaded_size ) {
static $previousProgress = 0;
if ( $download_size != 0 ) {
$progress = round( $downloaded_size * 100 / $download_size );
if ( $progress > $previousProgress ) {
$previousProgress = $progress;
//update javacsript progress bar to show download progress
echo "<script>updateProgress('$progress');</script>";
ob_flush();
flush();
}
}
}
//Start the curl
$targetFile = fopen( 'testfile.iso', 'w' );
$ch = curl_init( 'https://ftp.free.org/mirrors/releases.ubuntu.com/releases/20.04/ubuntu-20.04.3-live-server-amd64.iso' );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt( $ch, CURLOPT_NOPROGRESS, false );
curl_setopt( $ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback' );
curl_setopt( $ch, CURLOPT_FILE, $targetFile );
curl_exec( $ch );
fclose( $targetFile );
//if we get here, the download has completed
echo "<script>document.getElementById('info').innerHTML = 'Done';</script>";
//flush just to be sure
ob_flush();
flush();
?>
@oleteacher
Copy link

Outstanding! Just what I was looking for after finding the gist you forked.

Thank you for sharing.

@Leandro-Reis
Copy link

Outstanding! indeed. Thanks men.

@placecodex
Copy link

thanks bro

@shoyebsheikh
Copy link

How can you do this if the curl is executing via ajax ?

@stuudmuffin
Copy link
Author

stuudmuffin commented Oct 5, 2021

How can you do this if the curl is executing via ajax ?

Curl in this sense is a server-side process, and is not ajax. The server is downloading the file, not the client web browser. In the typical use of php-curl, it will be called before the page is rendered and has nothing to do with the client's capabilities. In our case, we're force flushing the buffer to output the page to the client, before it's been fully rendered, or before the file is 100% downloaded. This is what allows us to send progress updates to the client on how far along the server side download is.

@shoyebsheikh
Copy link

I get your point, ob statements wont work after the DOM is fully rendered.
I am doing this whole process in ajax i.e my curl is executing in ajax.
I am looking for a workaround to get it working like this example, any suggestions ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment