简体   繁体   中英

How can I download, then delete a file on my website with PHP?

I generate a *.csv file with PHP and it works great. The problem is, it contains a bunch of sensitive data. I've done my permissions very carefully, so you can't get to the download link or generate the file without being the correct user. The issue that I run into, is that right after the user downloads the file, the file needs to be deleted right away. The chance is small, I realize, that someone would be sitting there scanning my site structure, but the data is important enough to where I want to cover my ass:-)

I had this at first:

<a href="<?php echo base_path().$ourFileName ?>"><?=$ourFileName?></a>

Which works great to just download the file, but I was having a hard time doing any kind of actions with it, because if you nest PHP code inside an OnClick="" it will be executed before the click happens, because all PHP code is rendered server-side before the HTML and JAVASCRIPT is processed...right? I searched the internet, and it didn't seem like I could get javascript to have the perms to delete the file...admittedly, I could be very wrong.

So I turned my link into a form:

<?PHP
if(isset($_POST['submit']))
{
    header("Location: ".base_path().$ourFileName);
    unlink(base_path().$ourFileName);
}?>

<form action="<? $PHP_SELF ?>" method="post">
<input type="submit" value="Submit" name="submit">
</form>

But obviously, the unlink() will never be reachable because of the header...at least I think... Is there another way besides header() to download the file to them? I realize I could just run a cron job every minute or something and just:

rm -rf *.csv

And that would take care of the issue, but what happens if a user is in the process of downloading the file and cron starts to run? Or the page is generated, but they don't click on the link for a while for some reason?

Maybe there's some way to configure my .htaccess file so you can only access the file if linking from a page?

Am I over complicating this?

Any ideas gurus of the interweb?

--edit Per popular suggestion, I'm working on the new header format so the code looks like this:

<?PHP if(isset($_POST['submit']) && ($user->uid))
{
    myroom_render_csv($ourFileName, $csv_string);
}?>

<form action="<? $PHP_SELF ?>" method="post">
<input type="submit" value="Submit" name="submit">
</form>

and in a separate file:

<?PHP function myroom_render_csv($file_name, $csv_string) {
header('Content-type: text/csv');
$header_string2="Content-Disposition: attachment; filename=\"".$file_name."\"";
header($header_string2);
echo $csv_string;
} ?>

but I get a dump of the full HTML page AND the CSV data. Ideas?

Here's a simpler solution - don't create a file. Instead of writing your data to a.csv file, just set the headers in a php script like so:

header('Content-type: text/csv');
header('Content-Disposition: attachment; filename="whatever.csv"');

echo $csv_data;

Print out your csv data in the php script, and the browser will treat it like a file download. This way, you're free to control to who and when the file is accessible.

A few comments.


Which works great to just download the file, but I was having a hard time doing any kind of actions with it, because if you nest PHP code inside an OnClick="" it will be executed before the click happens, because all PHP code is rendered server-side before the HTML and JAVASCRIPT is processed...right? I searched the internet, and it didn't seem like I could get javascript to have the perms to delete the file...admittedly, I could be very wrong.

You're absolutely correct.


I generate a *.csv file with PHP and it works great. The problem is, it contains a bunch of sensitive data. I've done my permissions very carefully, so you can't get to the download link or generate the file without being the correct user. The issue that I run into, is that right after the user downloads the file, the file needs to be deleted right away. The chance is small, I realize, that someone would be sitting there scanning my site structure, but the data is important enough to where I want to cover my ass:-)

Then why is it a file? Just send it to the browser with the relevant headers to hint the browser to present it to the user as a saveable file resource. It doesn't have to be a physical file on the webserver for this.

Others have provided the code for this; I really just wanted to point out that you were correct about the client-side/server-side angle. :)


But obviously, the unlink() will never be reachable because of the header

Actually, no. header does not stop the script.

header("Location: ".base_path().$ourFileName);
unlink(base_path().$ourFileName);

Your unlink will have executed and finished long before the browser has gotten around to even starting the request for base_path().$ourFileName .

Usually, though, you should write exit to stop code processing after header :

header("Location: ".base_path().$ourFileName);
exit;
unlink(base_path().$ourFileName);

And now, as you say, yes, the unlink never occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM