PHP implements file resumption download
code:
<?php
//PHP resumable download
function download($fileurl, $start = 0, $end = '')
{
$task_sourcefile = '/path/downfile.mp4'; //Locally saved files
$sourceurl = $fileurl ; //The remote file to download
$tokenfile = 'downfile.token';
$isfileexist =$this->check_remote_file_exists($sourceurl);
if (!$isfileexist) {
$isfileexist2 =$this->check_remote_file_exists($sourceurl);
if (!$isfileexist2) {
throw new \Exception('The remote file does not exist');
}
}
if (!is_dir(dirname($tokenfile))) {
mkdir(dirname($tokenfile), 0777, true);
}
$sourcefilepath = dirname($task_sourcefile);
if (!is_dir($sourcefilepath)) {
@mkdir($sourcefilepath, 0777, true);
}
$ch = curl_init($sourceurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'SyncTask');
curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //Note that the timeout must be set to this
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 3600);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
curl_setopt($ch, CURLOPT_TIMEOUT, 600); //This option is the download timeout period, if the time is set short, if the download is not completed, it will be disconnected, and then resumption of download. If the setting is too long, the download may be stuck for a long time due to network reasons. Please set a reasonable value. It is recommended not to set it too long.
//curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100 * 1000); //Timeout milliseconds
curl_setopt($ch, CURLOPT_BUFFERSIZE, 20971520);
if ($end) {
curl_setopt($ch, CURLOPT_RANGE, "$start-$end");
} else {
curl_setopt($ch, CURLOPT_RANGE, "$start-");
}
$flag=$tag = 0;
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $str) use (&$flag, $task_sourcefile, $end, $sourceurl, $tokenfile, $start, &$tag) {
$len = strlen($str);
$flag++;
if ($flag==1) {
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
if ($length ==-1) {
$tag = 2;
return false;
}
if ($httpcode!=200 && $httpcode!=206) {
$tag = 2;
return false;
}
if ($start ==0) {
$data= ['name'=>$sourceurl,'size'=>$length];
file_put_contents($tokenfile, json_encode($data, JSON_UNESCAPED_UNICODE));
}
if ($end) {
if ($end-$start!=$length) {
$tag = 1;
return false;
}
}
}
file_put_contents($task_sourcefile, $str, FILE_APPEND|LOCK_EX);
return $len;
});
$output = curl_exec($ch);
if ($tag ==2 || $output===false) {
curl_close($ch);
clearstatcache();
download($fileurl, filesize($task_sourcefile), '');
}
if ($tag ==1) {
unlink($task_sourcefile);
unlink($tokenfile);
curl_close($ch);
download($fileurl, 0, '');
return true;
}
$tokeninfo = json_decode(file_get_contents($tokenfile), true);
$length = $tokeninfo['size'];
sleep(1);
clearstatcache();//This is to remove the cache of file information
if ($length!= filesize($task_sourcefile)) {
curl_close($ch);
echo 'Download error: length does not match ~~';
clearstatcache();
download($fileurl, filesize($task_sourcefile), '');
}
curl_close($ch);
return true;
}
//run
$download= download('http://www.test.com/333.mp4');
var_dump($download);
Leave a Reply