强制使用PHP下载文件

时间:2022-12-20 15:25:33

I have a CSV file on my server. If a user clicks on a link it should download, but instead it opens up in my browser window.

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

My code looks as follows

我的代码如下所示

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

It's a normal webserver where I have all of my development work on.

这是一个普通的webserver,我所有的开发工作都在这里进行。

I tried something like:

我试着喜欢的东西:

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

Now the contents of my csv.php file:

csv的内容。php文件:

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

Now my issue is it's downloading, but not my CSV file. It creates a new file.

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

9 个解决方案

#1


99  

.htaccess Solution

To brute force all CSV files on your server to download, add in your .htaccess file:

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

AddType application/octet-stream csv

PHP Solution

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

#2


20  

Or you can do this using HTML5. Simply with

或者你也可以用HTML5实现。简单地用

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

#3


14  

This cannot be done reliably, since it's up to the browser to decide what to do with an URL it's been asked to retrieve.

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

You can suggest to the browser that it should offer to "save to disk" right away by sending a Content-disposition header:

您可以向浏览器建议,它应该通过发送一个内容配置头,立即提供“保存到磁盘”:

header("Content-disposition: attachment");

I'm not sure how well this is supported by various browsers. The alternative is to send a Content-type of application/octet-stream, but that is a hack (you're basically telling the browser "I'm not telling you what kind of file this is" and depending on the fact that most browsers will then offer a download dialog) and allegedly causes problems with Internet Explorer.

我不确定各种浏览器对它的支持程度。另一种选择是发送一种内容类型的应用程序/八进制流,但这是一种黑客行为(您基本上是在告诉浏览器“我没有告诉您这是什么文件”,这取决于大多数浏览器随后将提供下载对话框这一事实),并且据称会导致Internet Explorer出现问题。

Read more about this in the Web Authoring FAQ.

请在Web创作FAQ中阅读更多相关内容。

Edit You've already switched to a PHP file to deliver the data - which is necessary to set the Content-disposition header (unless there are some arcane Apache settings that can also do this). Now all that's left to do is for that PHP file to read the contents of the CSV file and print them - the filename=example.csv in the header only suggests to the client browser what name to use for the file, it does not actually fetch the data from the file on the server.

编辑您已经切换到一个PHP文件来交付数据—这是设置内容配置头的必要条件(除非有一些晦涩的Apache设置也可以这样做)。现在只剩下PHP文件读取CSV文件的内容并打印它们——filename=示例。头中的csv只向客户端浏览器建议文件使用什么名称,它实际上并不从服务器上的文件获取数据。

#4


12  

Here is a more browser-safe solution:

这里有一个更安全的浏览器解决方案:

    $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);

#5


7  

Configure your server to send the file with the media type application/octet-stream.

将服务器配置为使用媒体类型应用程序/八进制流发送文件。

#6


2  

This means that your browser can handle this file type.

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

If you don't like it, the easiest method would be offering ZIP files. Everyone can handle ZIP files, and they are downloadable by default.

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

#7


2  

Nice clean solution:

干净的解决方案:

<?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);
?>

#8


1  

A previous answer on this page describes how to use .htaccess to force all files of a certain type to download. However, the solution does not work with all file types across all browsers. This is a more reliable way:

本页面上的前一个答案描述了如何使用.htaccess强制下载特定类型的所有文件。但是,该解决方案并不适用于所有浏览器的所有文件类型。这是一个更可靠的方法:

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

You might need to flush your browser cache to see this working correctly.

您可能需要刷新浏览器缓存,才能看到此操作正确。

#9


0  

If you are doing it with your application itself... I hope this code helps.

如果您正在使用您的应用程序本身…我希望这段代码能有所帮助。

HTML

In href -- you have to add download_file.php along with your URL:

在href——必须添加download_file。php连同您的URL:

<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;
    }
?>

#1


99  

.htaccess Solution

To brute force all CSV files on your server to download, add in your .htaccess file:

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

AddType application/octet-stream csv

PHP Solution

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

#2


20  

Or you can do this using HTML5. Simply with

或者你也可以用HTML5实现。简单地用

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

#3


14  

This cannot be done reliably, since it's up to the browser to decide what to do with an URL it's been asked to retrieve.

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

You can suggest to the browser that it should offer to "save to disk" right away by sending a Content-disposition header:

您可以向浏览器建议,它应该通过发送一个内容配置头,立即提供“保存到磁盘”:

header("Content-disposition: attachment");

I'm not sure how well this is supported by various browsers. The alternative is to send a Content-type of application/octet-stream, but that is a hack (you're basically telling the browser "I'm not telling you what kind of file this is" and depending on the fact that most browsers will then offer a download dialog) and allegedly causes problems with Internet Explorer.

我不确定各种浏览器对它的支持程度。另一种选择是发送一种内容类型的应用程序/八进制流,但这是一种黑客行为(您基本上是在告诉浏览器“我没有告诉您这是什么文件”,这取决于大多数浏览器随后将提供下载对话框这一事实),并且据称会导致Internet Explorer出现问题。

Read more about this in the Web Authoring FAQ.

请在Web创作FAQ中阅读更多相关内容。

Edit You've already switched to a PHP file to deliver the data - which is necessary to set the Content-disposition header (unless there are some arcane Apache settings that can also do this). Now all that's left to do is for that PHP file to read the contents of the CSV file and print them - the filename=example.csv in the header only suggests to the client browser what name to use for the file, it does not actually fetch the data from the file on the server.

编辑您已经切换到一个PHP文件来交付数据—这是设置内容配置头的必要条件(除非有一些晦涩的Apache设置也可以这样做)。现在只剩下PHP文件读取CSV文件的内容并打印它们——filename=示例。头中的csv只向客户端浏览器建议文件使用什么名称,它实际上并不从服务器上的文件获取数据。

#4


12  

Here is a more browser-safe solution:

这里有一个更安全的浏览器解决方案:

    $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);

#5


7  

Configure your server to send the file with the media type application/octet-stream.

将服务器配置为使用媒体类型应用程序/八进制流发送文件。

#6


2  

This means that your browser can handle this file type.

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

If you don't like it, the easiest method would be offering ZIP files. Everyone can handle ZIP files, and they are downloadable by default.

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

#7


2  

Nice clean solution:

干净的解决方案:

<?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);
?>

#8


1  

A previous answer on this page describes how to use .htaccess to force all files of a certain type to download. However, the solution does not work with all file types across all browsers. This is a more reliable way:

本页面上的前一个答案描述了如何使用.htaccess强制下载特定类型的所有文件。但是,该解决方案并不适用于所有浏览器的所有文件类型。这是一个更可靠的方法:

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

You might need to flush your browser cache to see this working correctly.

您可能需要刷新浏览器缓存,才能看到此操作正确。

#9


0  

If you are doing it with your application itself... I hope this code helps.

如果您正在使用您的应用程序本身…我希望这段代码能有所帮助。

HTML

In href -- you have to add download_file.php along with your URL:

在href——必须添加download_file。php连同您的URL:

<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;
    }
?>