我用PHP编写了一个文件下载脚本,该脚本使用户可以从我的服务器下载任何指定的文件。该脚本可以很好地处理.txt,.pdf和.jpg等文件。
但是,当用户尝试下载任何.mp3或.mp4文件时,尽管脚本会下载文件,但该文件不可用。与我的原始文件相比,该文件的大小要小得多。该文件无法在任何媒体播放器中打开-它已损坏。
我不知道我的下载脚本出了什么问题。这是完整的代码:
界面页面(index.php):
<a href="download.php?file=tutorial.pdf">Download Tutorial (pdf)</a><br /><br />
<a href="download.php?file=music.mp3">Download Music (mp3)</a><br /><br />
<a href="download.php?file=video.mp4">Download Video (mp4)</a>
PHP脚本(download.php):
<?php
if(isset($_GET['file']) && !empty($_GET['file']))
{
$file = $_GET['file'];
$file_without_spaces = str_replace(' ', "%20", $file);
$path_parts = pathinfo($file);
$file_name = $path_parts['basename'];
$file_path = "files/" . $file_name;
$file_extension = $path_parts['extension'];
if(!is_readable($file_path))
{
die("File not found!");
}
// Figure out the correct MIME type
$mime_types = array(
// Documents
"pdf" => "application/pdf",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"csv" => "application/csv",
"txt" => "text/plain",
// Archives
"zip" => "application/zip",
// Executables
"exe" => "application/octet-stream",
// Images
"jpg" => "image/jpeg",
"jpeg" => "image/jpeg",
"png" => "image/png",
"gif" => "image/gif",
"bmp" => "image/bmp",
// Audio
"mp3" => "audio/mpeg",
"wav" => "audio/x-wav",
// Video
"mpeg" => "video/mpeg",
"mpg" => "video/mpeg",
"mov" => "video/quicktime",
"avi" => "video/x-msvideo",
"mp4" => "video/mp4",
"3gp" => "video/3gpp"
);
if(array_key_exists($file_extension, $mime_types))
{
$mime_type = $mime_types[$file_extension];
}
header("Content-type: " . $mime_type);
header("Content-Disposition: attachment; filename=\"$file_without_spaces\"");
readfile($file_path);
}
?>
我下载了一个很大的.mp4
文件,大小约为250 MB。出来的只有2 KB。我在记事本中发现了此错误:
致命错误:允许的内存大小为...
答案 0 :(得分:0)
在OP添加自己的答案之前,我将对此有所了解...
致命错误:允许的内存大小为...
PHP manual page for readfile()
中有一个非常具体的注释。它说...
readfile()本身不会出现任何内存问题,即使发送大文件也是如此。如果遇到内存不足错误,请确保使用
关闭输出缓冲ob_get_level()
我怀疑这是问题所在。
要禁用输出缓冲,请确保将output_buffering
runtime configuration设置为0
。
对此特定问题有一些额外的改进...
使用exit
readfile($file_path);
exit;
使用URL编码整个文件的基本名称,而不是仅用%20
代替空格
header(sprintf('Content-Disposition: attachment; filename="%s"',
urlencode($file_name));