从服务器下载文件PHP

16

我有一个URL,里面保存了我工作的一些项目,主要是MDB文件,但也有一些JPG和PDF文件。

我需要做的是列出该目录中的每个文件(已完成),并给用户提供下载选项。

如何使用PHP实现这一点?


1
这不是由浏览器处理吗? - SomeKittens
1
但是我该如何让浏览器开始下载? - Gustavo Benito Silva
4个回答

43

您可以使用readdir()函数来读取目录内容,并使用一个脚本(例如我的示例中的download.php)下载文件。

if ($handle = opendir('/path/to/your/dir/')) {
    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
            echo "<a href='download.php?file=".$entry."'>".$entry."</a>\n";
        }
    }
    closedir($handle);
}

download.php中,您可以强制浏览器发送下载数据,并使用basename()来确保客户端不会传递其他文件名,例如../config.php

$file = basename($_GET['file']);
$file = '/path/to/your/dir/'.$file;

if(!file_exists($file)){ // file does not exist
    die('file not found');
} else {
    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=$file");
    header("Content-Type: application/zip");
    header("Content-Transfer-Encoding: binary");

    // read the file from disk
    readfile($file);
}

我收到了一个403错误消息;检查了文件夹权限,已设置为777,所以我不知道出了什么问题。 - Gustavo Benito Silva
请确保路径正确...文件夹和文件的路径。 - Mihai Iorga
请检查您的文件所在目录中的.htaccess文件内容。 - Cary Millsap
应该始终检查文件名是否是有效的文件名,而且不包含不应存在的字符。例如,../../../config.php 可能允许下载网站的主配置文件。 - Andrew Killen

3

这里是能避免下载损坏文件的代码

$filename = "myfile.jpg";
$file = "/uploads/images/".$filename;

header('Content-type: application/octet-stream');
header("Content-Type: ".mime_content_type($file));
header("Content-Disposition: attachment; filename=".$filename);
while (ob_get_level()) {
    ob_end_clean();
}
readfile($file);

我已经包含了mime_content_type函数,它将返回文件的内容类型。

为了防止损坏的文件下载,我已添加了ob_get_level()和ob_end_clean()函数。


2
如果您可以从浏览器中访问文件夹(不在Web服务器文档根目录之外),那么您只需要输出到这些文件位置的链接。如果它们在文档根目录之外,您需要有一个指向处理获取文件并流式传输到响应的PHP脚本的链接、按钮或其他内容。

如果文件是图像或文本,则不会下载它。 - Mihai Iorga
如果它是在浏览器中打开的文件,您可以使用浏览器的保存功能将其保存到文件系统中。任务仍然完成。 - Brian Warshaw
如果你能告诉客户,我已经了解到大多数“消费者”不知道如果在浏览器中打开文本文件或PDF文件该怎么做。 - Mihai Iorga

2

这里有一个更简单的解决方案,可以列出目录中的所有文件并下载它。

在您的index.php文件中

<?php
$dir = "./";

$allFiles = scandir($dir);
$files = array_diff($allFiles, array('.', '..')); // To remove . and .. 

foreach($files as $file){
     echo "<a href='download.php?file=".$file."'>".$file."</a><br>";
}

scandir()函数列出指定路径内的所有文件和目录。它适用于PHP 5和PHP 7。

现在在download.php中使用该函数。

<?php
$filename = basename($_GET['file']);
// Specify file path.
$path = ''; // '/uplods/'
$download_file =  $path.$filename;

if(!empty($filename)){
    // Check file is exists on given path.
    if(file_exists($download_file))
    {
      header('Content-Disposition: attachment; filename=' . $filename);  
      readfile($download_file); 
      exit;
    }
    else
    {
      echo 'File does not exists on given path';
    }
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接