I have a php script on a web server that uploads a file to another remote server via ftp_put.
How can I display the current upload progress to the user?
The
It can be implemented easily using FTP URL protocol wrappers:
$url = "ftp://username:password@ftp.example.com/remote/dest/path/file.zip";
$local_path = "/local/source/path/file.zip";
$size = filesize($local_path) or die("Cannot retrieve size file");
$hout = fopen($url, "wb") or die("Cannot open destination file");
$hin = fopen($local_path, "rb") or die("Cannot open source file");
while (!feof($hin))
{
$buf = fread($hin, 10240);
fwrite($hout, $buf);
echo "\r".intval(ftell($hin)/$size*100)."%";
}
echo "\n";
fclose($hin);
fclose($hout);
If ftp server on other machine supports REST
command (restart uploading from certain point) there is dirty way to implement this:
Sample code:
$fs = filesize('file.bin');
define('FTP_CHUNK_SIZE', intval($fs * 0.1) ); // upload ~10% per iteration
$ftp = ftp_connect('localhost') or die('Unable to connect to FTP server');
ftp_login($ftp, 'login', 'pass') or die('FTP login failed');
$localfile = fopen('file.bin','rb');
$i = 0;
while( $i < $fs )
{
$tmpfile = fopen('tmp_ftp_upload.bin','ab');
fwrite($tmpfile, fread($localfile, FTP_CHUNK_SIZE));
fclose($tmpfile);
ftp_put($ftp, 'remote_file.bin', 'tmp_ftp_upload.bin', FTP_BINARY, $i);
// Remember to put $i as last argument above
$progress = (100 * round( ($i += FTP_CHUNK_SIZE) / $fs, 2 ));
file_put_contents('ftp_progress.txt', "Progress: {$progress}%");
}
fclose($localfile);
unlink('ftp_progress.txt');
unlink('tmp_ftp_upload.bin'); // delete when done
And file to check with ajax:
if(file_exists('ftp_progress.txt'))
echo file_get_contents('ftp_progress.txt');
else
echo 'Progress: 0%';
exit;