将PHP与可恢复下载和加密文件一起使用
我有一个项目,加密上传的文件并保存它们。这些文件对用户隐藏,同时仍然可以使用php查看它们 下面的代码适用于图像和大小为0-2MB的所有其他文件。问题是用于发送到浏览器的大于2MB的文件在请求的字节范围内。喜欢HTML5视频的视频 有很多类似的问题,但我仍然没有得到,以处理加密的大文件 如何让这段代码在处理大文件和解密时正常工作,以便用户浏览器能够理解并显示内容?是否有一些标题我遗漏了什么或我做错了什么 以下是当前代码:将PHP与可恢复下载和加密文件一起使用,php,http,encryption,download,resume-download,Php,Http,Encryption,Download,Resume Download,我有一个项目,加密上传的文件并保存它们。这些文件对用户隐藏,同时仍然可以使用php查看它们 下面的代码适用于图像和大小为0-2MB的所有其他文件。问题是用于发送到浏览器的大于2MB的文件在请求的字节范围内。喜欢HTML5视频的视频 有很多类似的问题,但我仍然没有得到,以处理加密的大文件 如何让这段代码在处理大文件和解密时正常工作,以便用户浏览器能够理解并显示内容?是否有一些标题我遗漏了什么或我做错了什么 以下是当前代码: <?php function printFileChunksRang
<?php
function printFileChunksRange($file, $key){
//$_SERVER["HTTP_RANGE"]="bytes=0-"; // For testing
$fp = fopen($file['url'], 'rb');
$size = $file['size']; // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
$chunkSize = 1024*100; // Chunk size used to crypt files
$readChunkSize = $chunkSize+8; // Chunk size + IV size
// parse the range of bytes
if(!empty($_SERVER['HTTP_RANGE'])){
if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)){
$start = intval($matches[1]); // Start byte
if(!empty($matches[2])){
$end = intval($matches[2]); // End byte
}
}
}
if($start > $end) $end = $file['size']-1;
$length = $end-$start;
if(isset($_SERVER['HTTP_RANGE'])) header('HTTP/1.1 206 Partial Content'); // Send the header code 206 if range is requested...
else header('HTTP/1.1 200 OK'); // ...otherwise send 200
// Set the rest of headers
header("Content-type: {$file['type']}"); // File type
header('Cache-Control: public, must-revalidate, max-age=0'); // ...
header('Accept-Ranges: bytes'); // Say that ranges is accepted
if(isset($_SERVER['HTTP_RANGE'])) header("Content-Range: bytes {$start}-{$end}/{$file['size']}"); // Tell that what bytes we'll send
header("Content-Length: ".(($end-$begin)+1)); //$length // Content length
//Header("Connection: close");
// Count the chunk sizes.. etc. ...for the start of requested range
$chunk_start = intval(floor($start/$chunkSize));
$chunk_start_bytes = intval($chunk_start*$readChunkSize);
$chunk_start_remainder = intval($start % $chunkSize);
// Count the chunk sizes.. etc. ...for the end of requested range
$chunk_end = intval(floor($end/$chunkSize));
$chunk_end_bytes = intval($chunk_end*$readChunkSize);
$chunk_end_remainder = intval(($end+1) % $chunkSize);
fseek($fp, $chunk_start_bytes); // Seek the right byte to start reading
set_time_limit(0); // Set time limit to 0, for large files
$current = 0; // Current output length
while(!feof($fp) and $current <= $length and connection_status() == 0) {
$data = fread($fp, $readChunkSize); // Read encrypted chunk...
$data = $this->decrypt($data, $key); // ...and decrypt it
if($start+$end < $chunkSize) $data = substr($data, $chunk_start_remainder, $chunk_end_remainder-$chunk_start_remainder);
elseif($current + strlen($data) > $length+1) $data = substr($data, $chunk_start_remainder, $chunk_end_remainder);
else $data = substr($data, $chunk_start_remainder);
$chunk_start_remainder = 0; // Set remainder to 0, because we have already used it and we don't need it anymore;
$current += strlen($data); // Add $data length to $current output length
echo $data; // Print the decrypted chunk
flush(); // Free up memory to save server's resources
}
fclose($fp); // Close the file handle
}
?>
以及上述代码的用法:
<?php
$file = array(
'type' => 'video/mp4',
'ext' => 'mp4',
'name' => '6XjQALY3YG',
'size' => '15765276',
'original_name' => '20130908.mp4',
'key' => 'feab20c63f84788ad7cb90b547946bccb5da8a9d0b4ffb6473c70a732ae8df99',
'url' => 'upload/2013/12/17/6XjQALY3YG',
//'url' => 'bigfile.mp4',
);
printFileChunksRange($file, $file['key']);
?>
这里面有什么问题吗?你有错误吗?意外输出?如果它可以处理10mb的文件,那么较大的文件也不会成为问题。我建议检查输出缓冲区,或者创建一个seperate输出脚本,该脚本将readfile用于我已成功用于无限长实时视频流的脚本。另请参见此处的评论。其他需要说明的是php中的最大执行时间,请参见