1

I have a PHP script that is working fine for displaying all my images in a directy that I upload to. I wand to make a little download button so someone can click the button and download the image. I am making this for my company so people can download our logos.

<?php
        // Find all files in that folder
        $files = glob('grips/*');

        // Do a natural case insensitive sort, usually 1.jpg and 10.jpg would come next to each other with a regular sort
        natcasesort($files);


        // Display images
        foreach($files as $file) {
           echo '<img src="' . $file . '" />';
        }

    ?>

I figue I could just make a button and call the href of $file but that would just link to the file and show the image. I am not sure to have it auto download. Any help would be great.

Packy
  • 3,405
  • 9
  • 50
  • 87
  • 1
    possible duplicate of http://stackoverflow.com/q/40943/1150613... There's also a `download` attribute in html5, but it isn't very widely supported. *yet* – brbcoding May 29 '13 at 18:16

1 Answers1

0

Just add some headers in a download.php file so you can then read the file in like this:

Make sure you sanitize your data coming to the file, you don't want people to be able to download your php files.

<?php
    // Find all files in that folder
    $files = glob('grips/*');

    // Do a natural case insensitive sort, usually 1.jpg and 10.jpg would come next to each other with a regular sort
    natcasesort($files);


    // Display images
    foreach($files as $file) {
       echo '<img src="' . $file . '" /><br /><a href="/download.php?file='.base64_encode($file).'">Download Image</a>';
    }

?>

download.php

$filename = base64_decode($_GET["file"]);

// Data sanitization goes here
if(!getimagesize($filename) || !is_file($filename)){
    // Not an image, or file doesn't exist. Redirect user
    header("Location: /back_to_images.php");
    exit;
}

header("Pragma: public"); 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header("Content-Disposition: attachment; filename=".basename($filename).";"); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: ".filesize($filename)); 

readfile($filename); 
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • Please dear god, sanitize $_GET['file']! Don't allow everything! – Farkie May 29 '13 at 18:20
  • So you are saying keep the same code I have, make each file into like a list inside a form so when the click "download" it posts to download.php? and `$filename = "path/to/file.jpg";` would just be `$filename = "the path that got sent from the form.jpg";` – Packy May 29 '13 at 18:29
  • @Packy yes, just replace `$filename` with the path to the image, where the path is a *relative* location to `download.php` NOT *absolute* – Get Off My Lawn May 29 '13 at 18:32
  • @RyanNaddy I kind of get this. Obviously the file would always be changing so would I just use `$filename = "$file";` from the original code? – Packy May 29 '13 at 19:27
  • @Packy I updated the answer, take a look at the link I added (next to the img tag), and then at the first line of `download.php` – Get Off My Lawn May 29 '13 at 20:05
  • @RyanNaddy thanks. that worked great for encoding the images and the link. I get a 404 Error "/download.php?file=Z3JpcHMvbG9nby5wbmc=". Thanks for all the help on this. – Packy May 29 '13 at 20:50
  • I assume the 404 you get is from the downloaded file, if so, make sure download.php is pointing to the correct location of the image. – Get Off My Lawn May 29 '13 at 21:03
  • @RyanNaddy where would I do that? `$filename = ('grips/'.base64_decode($_GET["file"]).;` – Packy May 29 '13 at 21:51
  • @Packy that looks like it would work, just get rid of the `.` before the semi-colon. – Get Off My Lawn May 29 '13 at 21:53
  • @RyanNaddy worked great. The download.php was not getting called right. Thanks a tonQ – Packy May 29 '13 at 22:39