【发布时间】:2020-06-22 13:59:45
【问题描述】:
我目前正在用 PHP 开发文件下载。为此,我在服务器上创建了一个存储文件夹,并使用.htaccess 文件(全部拒绝)对其进行保护,因此无法通过在浏览器中输入路径来访问它。在这个文件夹中,我有一个文件5eecc057489de.jpeg,我现在要下载它:
htdocs/
└── files/
└── storage/
├── 5eecc057489de.jpeg
├── index.php
└── .htaccess
(我的 index.php 在根 htdocs 文件夹中)
为了安全和灵活,我想进行可恢复下载,并尝试找到一个适合我和我的客户需求的好脚本。所以我做了很多研究,从 Armand Niculescu 找到了这个脚本 - media-division.com:
/**
* Send download file to the browser
*
* @param $file
* @param string $filename
* @param string $file_ext
* @param bool $preview
* @param bool $open_pdf_in_browser
*
* @return void
*/
private function download_file( $file, $filename, $file_ext, $preview = false, $open_pdf_in_browser = false ): void {
while ( ob_get_level() ) {
ob_end_clean();
}
ini_set( 'error_reporting', E_ALL & ~E_NOTICE );
ini_set( 'zlib.output_compression', 'Off' );
$is_attachment = isset( $_REQUEST['stream'] ) ? false : true;
if ( $open_pdf_in_browser && $preview && strtolower( $file_ext ) === 'pdf' ) {
$is_attachment = false;
}
if ( file_exists( $file ) ) {
$file_size = filesize( $file );
$file_handler = fopen( $file, 'rb' );
if ( $file_handler ) {
header( 'Pragma: public' );
header( 'Expires: -1' );
header( 'Cache-Control: public, must-revalidate, post-check=0, pre-check=0' );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
if ( $is_attachment ) {
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
} else {
header( 'Content-Disposition: inline; filename="' . $filename . '"' );
}
header( 'Content-Type: ' . $this->mime_type( $file_ext ) );
// todo: Apply multiple ranges
if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
[ $size_unit, $range_orig ] = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
if ( $size_unit === 'bytes' ) {
[ $range ] = explode( ',', $range_orig, 2 );
} else {
header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
exit;
}
} else {
$range = '';
}
[ $seek_start, $seek_end ] = explode( '-', $range, 2 );
$seek_start = ( empty( $seek_start ) || $seek_end < abs( (int) $seek_start ) ) ? 0 : max( abs( (int) $seek_start ), 0 );
if ( $seek_start > 0 || $seek_end < ( $file_size - 1 ) ) {
header( 'HTTP/1.1 206 Partial Content' );
header( 'Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $file_size );
header( 'Content-Length: ' . ( $seek_end - $seek_start + 1 ) );
} else {
header( 'Content-Length: ' . $file_size );
}
header( 'Accept-Ranges: bytes' );
set_time_limit( 0 );
fseek( $file_handler, $seek_start );
while ( ! feof( $file_handler ) ) {
print( fread( $file_handler, 1024 * 8 ) );
ob_flush();
flush();
if ( connection_status() !== 0 ) {
fclose( $file_handler );
exit;
}
}
fclose( $file_handler );
exit;
}
header( 'HTTP/1.0 500 Internal Server Error' );
exit;
}
header( 'HTTP/1.0 404 Not Found' );
exit;
}
我做了一些最小的更改,例如变量名称更改(linter)和一些格式设置,但总而言之,我保留了原来的脚本。
要立即下载文件,我已从index.php 使用以下参数调用该函数:
$file = '/htdocs/files/storage/5eecc057489de.jpeg';
$filename = 'test.jpeg'; //This comes from the DB by doing a select with the unique file id: 5eecc057489de
$file_ext = 'jpeg';
$this->download_file( $file, $filename, $file_ext );
但是,经过我所有的尝试、调试和日志检查(没有条目) - 下载的文件有错误。 Chrome 尝试下载它,一切看起来都很好,但每次下载在开始后 1-2 秒中止并且文件下载完全失败:
我首先删除了 .htaccess 以确保它不是问题,但它没有帮助。
接下来尝试联系开发人员并向他寻求帮助,但没有得到答复(我的意思是脚本是 2012 年的)。所以也许你们中的某个人知道这里发生了什么?如果没有 - 您是否知道更好的脚本或做过同样的事情并且可以指出我下载可恢复文件的正确方法?
如果您需要更多信息,请给我留言!
【问题讨论】:
标签: php wordpress file plugins download