【问题标题】:How to download a temporary file如何下载临时文件
【发布时间】:2013-03-13 16:18:02
【问题描述】:

我正在尝试创建一个简短的 PHP 脚本,该脚本采用 JSON 字符串,将其转换为 CSV 格式(使用 fputcsv),并将该 CSV 作为下载的 .csv 文件提供。我的想法是使用 tmpfile() 来不用担心 cronjobs 或磁盘空间不足,但我似乎无法让魔法发生。

这是我的尝试,这是从the PHP docs of readfile 转换的示例:

$tmp = tmpfile();
$jsonArray = json_decode( $_POST['json'] );
fputcsv($tmp, $jsonArray);

header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.basename($tmp));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmp));

ob_clean();
flush();
readfile($tmp);

我觉得 Content-DispositionContent-Transfer-Encoding 标头是错误的,但我不确定如何修复它们。例如,basename($tmp) 似乎没有返回任何内容,我不确定text/csv 是否作为二进制编码传输。同样,echo filesize($tmp) 也是空白的。有没有办法做我在这里尝试的事情?

[编辑]

**以下是我根据接受的答案编写的工作代码:*

$jsonArray = json_decode( $_POST['json'], true );
$tmpName = tempnam(sys_get_temp_dir(), 'data');
$file = fopen($tmpName, 'w');

fputcsv($file, $jsonArray);
fclose($file);

header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=data.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmpName));

ob_clean();
flush();
readfile($tmpName);

unlink($tmpName);

【问题讨论】:

  • 有关此问题的 javascript 解决方案,请查看stackoverflow.com/questions/4130849/…
  • json_decode 是否会返回 null
  • 所以文件只是不想被下载?并在浏览器中打开?这就是问题所在?

标签: php


【解决方案1】:

请注意,tmpfile() 返回文件句柄,但您拥有的所有函数都需要文件路径(即字符串),而不是句柄 - 特别是 basenamefilesizereadfile。所以这些函数调用都不能正常工作。 basename 也不会返回文件扩展名。随心所欲地称呼它,即

'Content-Disposition: attachment; filename=data.csv'

正如@Joshua Burns 所说,确保将数组传递给fputcsv 或使用assoc 参数。

【讨论】:

  • 这是解决问题所需的一切。我会将工作代码编辑到问题中,以便人们可以看到修复。谢谢!
【解决方案2】:

json_decode() 默认情况下将元素转换为对象而不是数组。 fputcsv() 期望传递的数据是一个数组。

我建议更改:

$jsonArray = json_decode( $_POST['json'] );

收件人:

$jsonArray = json_decode( $_POST['json'], True );

看看这是否不能解决你的问题。

在尝试解决此类问题时,我强烈建议启用 display_errors 并将 error_reporting 设置为 E_ALL 以查看您是否遗漏了某种错误:

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

// Rest of your code here

【讨论】:

    【解决方案3】:

    首先,检查这个字符串,我将其更改为:

    header('Content-Disposition: attachment; filename="'.basename($tmp).'"');
    

    我曾经遇到过问题,浏览器兼容性:)

    【讨论】:

      【解决方案4】:

      一个问题是tmpfile() 返回一个文件句柄,而filesize 将文件名作为参数。
      以下行:

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

      可能被评估为:

      header('Content-Length: 0');
      

      检查所有对 header() 的调用是否在任何输出发生之前执行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-13
        • 2012-11-28
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 2020-11-08
        • 1970-01-01
        • 2021-07-05
        相关资源
        最近更新 更多