强制使用PHP下载文件

时间:2009-09-23 12:06:18

标签: php http download

我的服务器上有一个CSV文件。如果用户点击了应该下载的链接,而是在浏览器窗口中打开它。

我的代码如下

<a href="files/csv/example/example.csv">
    Click here to download an example of the "CSV" file
</a>

这是一个普通的网络服务器,我可以完成所有的开发工作。

我尝试过类似的事情:

<a href="files/csv/example/csv.php">
    Click here to download an example of the "CSV" file
</a>

现在我的csv.php文件的内容:

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');

现在我的问题是它正在下载,但不是我的CSV文件。它会创建一个新文件。

10 个答案:

答案 0 :(得分:103)

.htaccess解决方案

要强制下载服务器上的所有CSV文件,请添加.htaccess文件:

AddType application/octet-stream csv

PHP解决方案

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");

答案 1 :(得分:22)

或者您可以使用HTML5执行此操作。只需

<a href="example.csv" download>download not open it</a>

答案 2 :(得分:15)

这是不可靠的,因为由浏览器决定如何处理要求检索的URL。

您可以通过发送Content-disposition标头建议向浏览器提供“保存到磁盘”:

header("Content-disposition: attachment");

我不确定各种浏览器是否支持这种情况。另一种方法是发送一个Content-type的application / octet-stream,但这是一个hack(你基本上是告诉浏览器“我不是在告诉你这是什么类型的文件”而且取决于大多数事实然后,浏览器将提供下载对话框)并据称导致Internet Explorer出现问题。

Web Authoring FAQ.

中详细了解相关信息

编辑您已经切换到PHP文件来传递数据 - 这是设置Content-disposition标头所必需的(除非有一些神秘的Apache设置也可以执行此操作)。现在剩下要做的就是让PHP文件读取CSV文件的内容并打印出来 - 标题中的filename=example.csv只向客户端浏览器建议用于文件的名称,实际上并不是从服务器上的文件中获取数据。

答案 3 :(得分:12)

这是一个更加浏览器安全的解决方案:

    $fp = @fopen($yourfile, 'rb');

    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header("Content-Transfer-Encoding: binary");
    header('Pragma: public');
    header("Content-Length: ".filesize($yourfile));
}
else
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header("Content-Transfer-Encoding: binary");
    header('Expires: 0');
    header('Pragma: no-cache');
    header("Content-Length: ".filesize($yourfile));
}

fpassthru($fp);
fclose($fp);

答案 4 :(得分:7)

配置服务器以使用媒体类型application/octet-stream发送文件。

答案 5 :(得分:3)

干净利落的解决方案:

<?php
    header('Content-Type: application/download');
    header('Content-Disposition: attachment; filename="example.csv"');
    header("Content-Length: " . filesize("example.csv"));

    $fp = fopen("example.csv", "r");
    fpassthru($fp);
    fclose($fp);
?>

答案 6 :(得分:2)

这意味着您的浏览器可以处理此文件类型。

如果您不喜欢它,最简单的方法是提供ZIP文件。每个人都可以处理ZIP文件,默认情况下可以下载。

答案 7 :(得分:1)

此页面上的上一个答案介绍了如何使用.htaccess强制下载某种类型的所有文件。但是,该解决方案不适用于所有浏览器中的所有文件类型。这是一种更可靠的方式:

<FilesMatch "\.(?i:csv)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

您可能需要刷新浏览器缓存才能看到此工作正常。

答案 8 :(得分:1)

如果您正在使用您的应用程序本身...我希望此代码有所帮助。

HTML

在href中 - 您必须将download_file.php与您的网址一起添加:

<a class="download" href="'/download_file.php?fileSource='+http://www.google.com/logo_small.png" target="_blank" title="YourTitle">

PHP

/* Here is the Download.php file to force download stuff */

<?php
    $fullPath = $_GET['fileSource'];
    if($fullPath) {
        $fsize = filesize($fullPath);
        $path_parts = pathinfo($fullPath);
        $ext = strtolower($path_parts["extension"]);

        switch ($ext) {
            case "pdf":
                header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Use 'attachment' to force a download
                header("Content-type: application/pdf"); // Add here more headers for diff. extensions
                break;

            default;
                header("Content-type: application/octet-stream");
                header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
        }

        if($fsize) { // Checking if file size exist
            header("Content-length: $fsize");
        }
        readfile($fullPath);
        exit;
    }
?>

答案 9 :(得分:0)

要强制下载,您可以使用Content-Type: application/force-download标头,大多数浏览器都支持该标头:

function downloadFile($filePath)
{
    header('Content-Type: application/force-download');
    header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
    header('Content-Length: ' . filesize($filePath));
    readfile($filePath);
}

更好的方式

以这种方式下载文件并不是最佳方法,特别是对于大文件。 PHP将需要额外的CPU /内存来读取和输出文件内容,处理大文件时可能会达到时间/内存限制。

更好的方法是使用PHP进行身份验证并授予对文件的访问权限,并且应使用X-SENDFILE方法将实际的文件服务委托给Web服务器(需要某些Web服务器配置):

在将Web服务器配置为处理X-SENDFILE之后,只需将readfile($filePath)替换为header('X-SENDFILE: ' . $filePath),Web服务器将负责文件服务,这将比使用PHP {{1} }。

(对于Nginx,请使用readfile标头代替X-Accel-Redirect

注意:如果最终下载空文件,则意味着您没有配置Web服务器来处理X-SENDFILE标头。检查上面的链接,了解如何正确配置您的Web服务器。