Reputation: 5012
I am using php to download a file and I want the file should get delete automatically from the server after successful completion of download. I am using this code in php.
$fullPath = 'folder_name/download.txt';
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
$fd = fopen ($fullPath, "r");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
fclose ($fd);
}
unlink($fullPath);
You can see in the code after download I am unlink the file. But if I do so corrupted file is getting downloaded. Because sometime the file getting deleted before it get download fully. Is there anyway in php to know that client download the file successfully then I can delete it? Any idea will be highly appreciated.
Upvotes: 13
Views: 15760
Reputation: 466
As far as I'm aware, you cannot use server-side PHP to detect whether the download has finished for the client. It seems ignore_user_abort()
is the answer to your question (see below), otherwise you may just delete the file after a set amount of time.
ignore_user_abort(true);
if (connection_aborted()) {
unlink($f);
}
Related/Duplicate on Stackoverflow:
Upvotes: 6
Reputation: 33
This may be a little buggy for large files but small ones on a fast connection I use this with no problems.
<?php
### Check the CREATE FILE has been set and the file exists
if(isset($_POST['create_file']) && file_exists($file_name)):
### Download Speed (in KB)
$dls = 50;
### Delay time (in seconds) added to download time
$delay = 5;
## calculates estimated download time
$timer = round(filesize($file_name) / 1024 / $dls + $delay);
###Calculates file size in kb divides by download speed + 5 ?>
<iframe width="0" height="0" frameborder="0" src="<?php echo $file_name;?>"></iframe>
<h2>Please Wait, Your Download will complete in: <span id="logout-timer"></span></h2>
<script>setTimeout(function(){ window.location = "<?php echo $_SERVER['PHP_SELF']?>?f=<?php echo $file_name;?>";},<?php echo $timer;?>000);</script>
Deletes the file
<?php
endif;
if (isset($_GET['f'])):
unlink($_GET['f']);
### removes GET value and returns to page's original url
echo "<script> location.replace('".$_SERVER['PHP_SELF']."')</script>";
endif;?>
Download timer set for each file in var seconds
<script>
var seconds=<?php echo $timer;?>;function secondPassed(){var a=Math.round((seconds-30)/60);var b=seconds%60;if(b<10){b="0"+b}document.getElementById('logout-timer').innerHTML=a+":"+b;if(seconds==0){clearInterval(countdownTimer);document.getElementById('logout-timer').innerHTML="Timer"}else{seconds--}}var countdownTimer=setInterval('secondPassed()',1000);
</script>
Upvotes: 0
Reputation: 1
Not sure it will work in almost all cases but try sleep(10); something to delay the deletion of the file for some specific time.
Upvotes: -1
Reputation: 1194
There is no way to know when the user finished downloading a file with PHP, I'd use a queue system to delete the file after n seconds of the request:
How to Build a PHP Queue System
Upvotes: 1
Reputation: 14811
If you really are downloading (instead of uploading, like code in your posts suggests), you might be interested in tmpfile function that is specifically designed to create files, that will be immediately removed on having its descriptors closed.
Upvotes: 2
Reputation: 24
Check the request, if the Range HTTP header is set, the client is downloading the file in pieces, it wants to download only a small part of the data at once (for example: Range: bytes=500-999). Normally this is handled by the webserver automatically, but in this case you have to handle it and send only the requested range back. Store the progress in session and deny access only if the client downloaded all of the pieces.
Upvotes: 0
Reputation: 625
Check the hash code of the file on the server and on the client side... You could check the hash code with the javascript(How to calculate md5 hash of a file using javascript) send it to server and then check if it is the same al on the server...
Upvotes: 1