удалить файл с сервера после загрузки в PHP
Я использую php для загрузки файла, и я хочу, чтобы файл автоматически удалялся с сервера после успешного завершения загрузки. Я использую этот код в 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);
вы можете увидеть в коде после загрузки я разблокирую файл. Но если я это сделаю, поврежденный файл загружается. Потому что когда-то файл удаляется, прежде чем он полностью загрузится. Есть ли в php, чтобы знать, что клиент успешно загружает файл, тогда я могу его удалить? Любой идея будет высоко оценена.
7 ответов
нет способа узнать, когда пользователь закончил загрузку файла с PHP, я бы использовал систему очередей для удаления файла через n секунд запроса:
насколько мне известно, вы не можете использовать серверный PHP для определения того, завершена ли загрузка для клиента. Кажется ignore_user_abort()
ответ на ваш вопрос (см. ниже), в противном случае вы можете просто удалить файл после определенного количества времени.
ignore_user_abort(true);
if (connection_aborted()) {
unlink($f);
}
связанный / дубликат на Stackoverflow:
Проверьте хэш-код файла на сервере и на стороне клиента... Вы можете проверить хэш-код с помощью JavaScript(Как вычислить md5 хэш файла с помощью javascript) отправьте его на сервер, а затем проверьте, является ли он тем же al на сервере...
Если вы действительно загружаете (вместо загрузки, как предлагает код в ваших сообщениях), вам может быть интересно tmpfile функция, специально разработанная для создания файлов, которые будут немедленно удалены при закрытии ее дескрипторов.
Проверьте запрос, если установлен HTTP-заголовок диапазона, клиент загружает файл по частям, он хочет загрузить только небольшую часть данных сразу (например: Range: bytes=500-999). Обычно это осуществляется через веб-сервер автоматически, но в этом случае вы должны обработать его и отправить только запрашиваемого диапазона. Сохраните прогресс в сеансе и запретите доступ только в том случае, если клиент загрузил все части.
Не уверен, что он будет работать почти во всех случаях, но попробуйте sleep (10); что-то, чтобы задержать удаление файла на определенное время.
это может быть немного багги для больших файлов, но маленькие на быстром соединении я использую это без проблем.
<?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>
перенаправляет на себя значение файла?f=$file_name
<script>setTimeout(function(){ window.location = "<?php echo $_SERVER['PHP_SELF']?>?f=<?php echo $file_name;?>";},<?php echo $timer;?>000);</script>
удаляет файл
<?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;?>
скачать таймер для каждого файла в var секунд
<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>