16

I have a URL where I save some projects from my work, they are mostly MDB files, but some JPG and PDF are there too.

What I need to do is to list every file from that directory (already done) and give the user the option to download it.

How is that achieved using PHP?

Florent
  • 12,310
  • 10
  • 49
  • 58

4 Answers4

43

To read directory contents you can use readdir() and use a script, in my example download.php, to download files

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

In download.php you can force browser to send download data, and use basename() to make sure client does not pass other file name like ../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);
}
Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
3

Here is the code that will not download courpt files

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

I have included mime_content_type which will return content type of file .

To prevent from corrupt file download i have added ob_get_level() and ob_end_clean();

Vikas Kandari
  • 1,612
  • 18
  • 23
2

If the folder is accessible from the browser (not outside the document root of your web server), then you just need to output links to the locations of those files. If they are outside the document root, you will need to have links, buttons, whatever, that point to a PHP script that handles getting the files from their location and streaming to the response.

Brian Warshaw
  • 22,657
  • 9
  • 53
  • 72
  • If file is image or text it will not download it. – Mihai Iorga Aug 23 '12 at 14:42
  • If it's a file that opens in the browser, you can use the browser's save functionality to save it to the file system. The mission is still accomplished. – Brian Warshaw Aug 23 '12 at 14:44
  • If you can tell that to customer, I've learned that most of `consumers` don't know what to do if they see a text file opened in browser, or a pdf file .. – Mihai Iorga Aug 23 '12 at 14:46
2

Here is a simpler solution to list all files in a directory and to download it.

In your index.php file

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

The scandir() function list all files and directories inside the specified path. It works with both PHP 5 and PHP 7.

Now in the 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';
    }
 }
Geordy James
  • 2,358
  • 3
  • 25
  • 34