php - php下载zip文件夹作为附件,找不到文件夹
问题描述
对于为什么找不到此文件夹,我感到有些茫然。我有一个脚本,在搜索数据库以$filename
根据存储的随机代码查找某人购买的商品后,应该简单地返回他们的文件。我的代码如下所示(包括 db 查询的尾端):
$stmt_2 -> bind_result($filename);
$stmt_2 -> fetch();
$stmt_2 -> close();
// For .zip files
$filepath='/media-files/Label/' . $filename;
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($filepath)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found.';
} else if (!is_readable($filepath)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable.';
} else {
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($filepath) . '"');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit;
}
}
当我运行此代码时,我收到“找不到文件”。绊倒的地方也是如此!is_file($filepath)
——但是,路径是正确的,并且拉链肯定在那里,所以我不确定这里出了什么问题。
在调试方面,我尝试删除检查,直接转到 headers 和 readfile,它返回一个空的 zip 文件夹。如果我通过 URL 直接导航到文件,那么有什么用...
更新
文件路径问题已修复,但我仍然无法下载文件。在所有尝试中,ERR_INVALID_RESPONSE
或者如果我尝试暴力下载文件,它会返回一个空文件。我尝试使用这些标题但没有成功:
header_remove();
ob_end_clean();
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
ob_end_flush();
exit;
它们是大型音频文件,这似乎是导致问题的原因......
解决方案
Nico Haase是绝对正确的,这是对路径的误解。这是一篇文章的链接,应该澄清一下: https ://phpdelusions.net/articles/paths
目前您的脚本正在尝试在以下位置查找文件:
/媒体文件/标签/file.zip
不是:
/var/www/myproject/media-files/Label/file.zip
链接的文章应为您提供所有必要的信息。
TLDR;
利用:
$filepath=$_SERVER['DOCUMENT_ROOT'].'/media-files/Label/' . $filename;
更新
由于文件大小问题,可能是 PHP 在尝试加载整个文件时耗尽了允许的内存。我们可以尝试类似:
flush();
$file = fopen($filepath, "r");
while(!feof($file)) {
// send the current file part to the browser
print fread($file, round(10 * 1024));
// flush the content to the browser
flush();
}
fclose($file);
flush() 存在一些问题,但我认为这是一个不错的选择。您可以阅读:https ://www.php.net/manual/en/function.flush
除此之外,总是有可能将文件拆分成更小的块。