首页 > 解决方案 > 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;

它们是大型音频文件,这似乎是导致问题的原因......

标签: php

解决方案


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

除此之外,总是有可能将文件拆分成更小的块。


推荐阅读