Удалить файл с сервера после загрузки в 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, чтобы знать, что клиент загружает файл успешно, тогда я могу его удалить? Любая идея будет высоко оценена.

Ответ 1

Невозможно узнать, когда пользователь закончил загрузку файла с помощью PHP, я бы использовал систему очередей для удаления файла через n секунд запроса:

Как создать систему очереди PHP

Ответ 2

Насколько мне известно, вы не можете использовать PHP на стороне сервера, чтобы определить, закончилась ли загрузка для клиента. Кажется, ignore_user_abort() является ответом на ваш вопрос (см. Ниже), в противном случае вы можете просто удалить файл по истечении установленного времени.

ignore_user_abort(true);
if (connection_aborted()) {
  unlink($f);
} 

Связанный/Дубликат в Stackoverflow:

Ответ 3

Проверьте хэш-код файла на сервере и на стороне клиента... Вы можете проверить хэш-код с помощью javascript (Как вычислить хэш файл md5 файла с помощью javascript) отправить его на сервер, а затем проверить, является ли он одним и тем же на сервер...

Ответ 4

Если вы действительно загружаете (вместо того, чтобы загружать, например, код в ваших предложениях), вас может заинтересовать tmpfile, которая специально предназначена для создания файлов, которые будут немедленно удалены при закрытии дескрипторов.

Ответ 5

Проверьте запрос, если задан заголовок HTTP диапазона, клиент загружает файл в куски, он хочет сразу загрузить только небольшую часть данных (например: Range: bytes = 500-999). Обычно это автоматически обрабатывается веб-сервером, но в этом случае вам необходимо обработать его и отправить обратно только запрошенный диапазон. Сохраняйте прогресс в сеансе и запрещайте доступ только в том случае, если клиент загрузил все части.

Ответ 6

Не уверен, что он будет работать практически во всех случаях, но попробует спать (10); что-то, чтобы отложить удаление файла в течение определенного времени.

Ответ 7

Это может быть небольшая ошибка для больших файлов, но небольшие при быстром подключении. Я использую это без проблем.

<?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> 

Перенаправляет в SELF со значением файла? 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 original url
    echo "<script> location.replace('".$_SERVER['PHP_SELF']."')</script>"; 
    endif;?>

Установить таймер загрузки для каждого файла в секундах

<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>