【问题标题】:Force download file with PHP giving empty file使用 PHP 强制下载文件,给出空文件
【发布时间】:2010-08-25 07:37:46
【问题描述】:

最终目标是让用户下载 .csv 文件。现在我只是在测试尝试下载一个简单的文本文件:test.txt。该文件中唯一的内容是“test”一词。

这是 files_to_download.php 的 HTML 代码

Test file: <a href='test.php?file=test.txt'>Test.txt</a>

test.php 的代码:

if(!(empty($_GET["file"])))
{
    $file_name = $_GET["file"];
    $path = "path/to/file";
    $fullPath = $path . $file_name;

    if(ini_get('zlib.output_compression'))
      ini_set('zlib.output_compression', 'Off');

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: inline; attachment; filename=\"$file_name\"");
    header("Content-Type: text/plain");
    header("Content-Transfer-Encoding: binary");
    readfile($fullPath);
}

我尝试了上述标题的变体,添加了更多并删除了其他标题。以上似乎是本网站上最常见的推荐。

我也尝试过改变

header("Content-Type: text/plain");

header("Content-Type: text/csv");

并获得相同的结果:空 .txt 或 .csv 文件。

当我从服务器直接打开它们(文件浏览器)时,文件不是空的。我检查了文件的权限,它们都是644,所以至少全世界都可以读取这些文件。目录是 777。

Apache 服务器上是否有我需要指定的配置可能没有或我缺少上面的某些内容。

感谢收看!

【问题讨论】:

  • 您应该检查$fullPath 并确保它是您想要的路径。在您的示例中,$fullPath"path/to/filetest.txt" 而不是 "path/to/file/test.txt"
  • 如果您将readfile($fullPath); 替换为echo 'foo',代码对我来说可以正常工作,所以我投票支持路径问题。

标签: php file download


【解决方案1】:

大多数情况下路径是错误的

【讨论】:

  • 这恰好是问题所在。我在一个页面中生成/导出了文件,然后可以在不同的页面上下载。麻烦的是,这个文件的路径和它的名字可以根据日期改变。因此,我将名称和目录传递给会话。问题是我没有在脚本顶部包含“session_start()”。现在就像一个魅力!
【解决方案2】:

读取文本文件,然后 echo 在您的 header() 调用后输出文本。

这是我设置 csv 下载的方法:

//downloads an export of the user DB
$csv = User::exportUsers();

header('Content-disposition: attachment; filename=userdb.csv');
header('Content-type: text/csv');

echo $csv;

exportUsers() 创建 csv 数据的位置。您可以轻松地将 $csv 替换为文本文件的内容,然后将其回显。

就您的文本文件而言,您可以使用file_get_contents() 将文件内容转换为字符串。然后回显该字符串。

【讨论】:

  • 这里的好处是您可以var_dump($csv) 确保它包含您认为包含的内容,然后再指责标题。
【解决方案3】:

尝试设置文件的内容长度:

header('Content-Length: ' . filesize($file));

另外,请记住这一点:file inclusion

【讨论】:

    【解决方案4】:

    就我而言,路径是正确的。强制下载在 windows 上有效,但在 mac 上无效。

    经过几次测试后,我发现标头 Content-Length 失败了。我在一个完整的 url 上使用了函数文件大小,比如:

    $url_my_file = "http://my-website.com/folders/file.ext";
    header('Content-Length: '.(filesize($url_my_file)));
    

    我把它替换为

    $url_my_file = "http://my-website.com/folders/file.ext";    
    $headers  = get_headers($url_my_file, 1);
    header('Content-Length: '.($headers['Content-Length']));
    

    而且......它现在正在工作:)

    【讨论】:

      猜你喜欢
      • 2010-11-03
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 2013-06-26
      相关资源
      最近更新 更多