PHP File Download From Table

Hi All

I’m a bit stuck, i currently have a form that logged in users enter information & submit a file. This uploads to a folder on the server and adds the file name to the database. However when displaying the data in a table i’m stuck on how to download the file based on the ID of the record.

Please can someone advise on how best to do this:-

Table:-

echo "<td>" . $row['dt_created'] . "</td>";
echo "<td>" . $row['file_name'] . "</td>";
echo "<td>";
echo "<a href='z_filedownload.php?id=". $row['id'] ."' title='Download File' data-toggle='tooltip'><span class='fas fa-download'></span></a>";
echo "</td>";

Download.php (i found this on a tut website but not sure how to link the download file based on the ID of the record)

<?php
if(isset($_REQUEST["file"])){
    // Get parameters
    $file = urldecode($_REQUEST["file"]); // Decode URL-encoded string
    $filepath = "uploads/files.htm/" . $file;
    
    // Process download
    if(file_exists($filepath)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($filepath));
        flush(); // Flush system output buffer
        readfile($filepath);
        exit;
    }
}
?>

Thanks in advance

This is the key bit - change this to use the path of your file from your database row.

    $filepath = "uploads/files.htm/" . $file;

If you can’t get it from there, I think you’d need to show your upload code so someone can see how you’ve named the files relative to the row id. Presumably in your download code, all you need to do is open the database, retrieve the row based on the id you pass in via the URL and use $row['file-name'].

Thanks droopsnoot. How would i change this to use the path of the file from the database row inside of download.php?

The files names remain the same of what was uploaded. i.e if the users file is called image.jpg it would upload the filename image.jpg to the table and move the file to files.htm.

As you said, all i’m looking to do is to download a file based on the row / row id

You know the code you posted at the start, which retrieves the row and displays the filename and date created? Use the same code to retrieve it from the database, and then instead of displaying it, put it into the line I highlighted.

And what happens when two users upload something with the same name? I often upload “capture.jpg” to places because that’s what the snipping tool calls a screen grab by default. Even if you have a separate directory for each user, that would cause me a problem in that example.

1 Like

Thank you. I think i was having a brain fart. I used:

echo "<a href='uploads/files.htm/". $row['file_name'] ."' title='Download File' data-toggle='tooltip'><span class='fas fa-download'></span></a>";

and it worked a treat. Thank you.

You’re absolutely right, the next step is to incorporate a file rename on upload. I’ve seen people using MD5 and rand along with time.
What would you suggest is the best way? (and not too difficult to implement as i’m still quite new to php).

Well that’s a good enough way of doing it, but it does rather expose your file storage. As it is only logged-in users that can download files, won’t that make it easy (or at least possible) for users to guess other files?

I’ve no proper experience of it so I wouldn’t like to suggest one. Anything that gives a unique name must be a decent enough way of doing it. Something as simple as using the row id, if it’s unique, would work well enough. You can always store the original image name as well, if it’s important.

1 Like

A very valid point, i did try as a precautionary measure to access the files through the address bar but i got a 404. Plus i named the file with .htm so that it wouldn’t/shouldn’t appear anywhere. What would you suggest as an alternative?

Thanks Droopsnoot, i’m definitely going to implement this. :+1:

Can i pick your brains again? :see_no_evil:

POST DELETED

Figured it out, i didnt set the update form to multipart/form-data… DOH! :crazy_face::man_facepalming: