У меня есть пользователь может загрузить файл с другого сервера / URL.
Это пример кода, но возобновляемая загрузка не работает, и при попытке загрузки начать с начала
<?php
$url = "http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/03/windows10.0-kb4012606-x64_e805b81ee08c3bb0a8ab2c5ce6be5b35127f8773.msu";
dl_file_resumable( $url );
function dl_file_resumable( $file, $is_resume = true ) {
//Gather relevent info about file
$size = remotefilesize( $file );
$fileinfo = pathinfo( $file );
//workaround for IE filename bug with multiple periods / multiple dots in filename
//that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
$filename = ( strstr( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) ) ?
preg_replace( '/\./', '%2e', $fileinfo['basename'], substr_count( $fileinfo
== [ 'basename' ], '.' ) - 1 ) : $fileinfo['basename'];
$file_extension = strtolower( $fileinfo['extension'] );
//This will set the Content-Type to the appropriate setting for the file
switch ( $file_extension ) {
case 'exe':
$ctype = 'application/octet-stream';
break;
case 'zip':
$ctype = 'application/zip';
break;
case 'rar':
$ctype = 'application/x-rar-compressed';
break;
case 'mp3':
$ctype = 'audio/mpeg';
break;
case 'mpg':
$ctype = 'video/mpeg';
break;
case 'avi':
$ctype = 'video/x-msvideo';
break;
default:
$ctype = 'application/force-download';
}
//check if http_range is sent by browser (or download manager)
if ( $is_resume && isset( $_SERVER['HTTP_RANGE'] ) ) {
list( $size_unit, $range_orig ) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
if ( $size_unit == 'bytes' ) {
//multiple ranges could be specified at the same time, but for simplicity only serve the first range
//http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
list( $range, $extra_ranges ) = explode( ',', $range_orig, 2 );
} else {
$range = '';
}
} else {
$range = '';
}
//figure out download piece from range (if set)
list( $seek_start, $seek_end ) = explode( '-', $range, 2 );
//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = ( empty( $seek_end ) ) ? ( $size - 1 ) : min( abs( intval( $seek_end ) ), ( $size - 1 ) );
$seek_start = ( empty( $seek_start ) || $seek_end < abs( intval( $seek_start ) ) ) ? 0 : max( abs( intval( $seek_start ) ), 0 );
//add headers if resumable
if ( $seek_start > 0 || $seek_end < ( $size - 1 ) ) {
header( 'HTTP/1.1 206 Partial Content' );
header( 'Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $size );
header( 'Content-Length: ' . ( $seek_end - $seek_start + 1 ) );
} else {
header( "Content-Length: $size" );
}
header( 'Accept-Ranges: bytes' );
//headers for IE Bugs (is this necessary?)
//header("Cache-Control: cache, must-revalidate");
//header("Pragma: public");
header( 'Content-Type: ' . $ctype );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
header( "Pragma: public" );
header( "Expires: -1" );
header( "Cache-Control: public, must-revalidate, post-check=0, pre-check=0" );
header( "Content-Disposition: attachment; filename=\"$filename\"" );
//open the file
$fp = fopen( $file, 'rb' );
//seek to start of missing part
fseek( $fp, $seek_start );
//start buffered download
while ( ! feof( $fp ) ) {
//reset time limit for big files
set_time_limit( 0 );
print( fread( $fp, 1024 * 8 ) );
flush();
ob_flush();
usleep(50000);
if ( connection_status() != 0 ) {
@fclose( $file );
exit;
}
}
fclose( $fp );
exit;
}
function remotefilesize( $url, $user = "", $pw = "" ) {
ob_start();
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_HEADER, 1 );
curl_setopt( $ch, CURLOPT_NOBODY, 1 );
if ( ! empty( $user ) && ! empty( $pw ) ) {
$headers = array( 'Authorization: Basic ' . base64_encode( "$user:$pw" ) );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
}
$ok = curl_exec( $ch );
curl_close( $ch );
$head = ob_get_contents();
ob_end_clean();
$regex = '/Content-Length:\s([0-9].+?)\s/';
$count = preg_match( $regex, $head, $matches );
return isset( $matches[1] ) ? $matches[1] : "unknown";
}
Я протестировал некоторый код, но похожее поведение
http://www.media-division.com/php-download-script-with-resume-option/
Задача ещё не решена.
Других решений пока нет …