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

11
Немає хорошого способу сказати, що завантаження завершено. Якщо файли, які ви прагнете завантажити, не великі, то найкраще, що ви можете зробити, це відправити їх по електронній пошті та негайно видалити їх.
додано Автор php_nub_qq, джерело
Чи можете ви зробити перевірку розміру файлу і порівняти його розміри, якщо вони однакові?
додано Автор Panama Jack, джерело
видалення файлів відбувається швидше, ніж завантаження файлу
додано Автор Jay Harris, джерело

7 Відповіді

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

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

Пов'язані/повторювані на Stackoverflow:

5
додано

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

1
додано
Це дійсно просто 'coz він може відкрити обидва файли - тоді використовувати stream_copy_to_stream - видалити старий файл і просто читати tmp файл - але це буде розірвати часткові завантаження :)
додано Автор Bartosz Grzybowski, джерело

Перевірте хеш-код файлу на сервері та на стороні клієнта ... Ви можете перевірити хеш-код за допомогою JavaScript ( Як розрахувати md5 хеш файлу за допомогою JavaScript ) відправити його на сервер і перевірити, якщо це той же аль на сервері ...

1
додано

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

Як створити систему черги PHP

1
додано

Це може бути трохи помилка для великих файлів, але малі на швидкому підключенні я використовую це без проблем.

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

Please Wait, Your Download will complete in:

 

Перенаправляє на 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's 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>
0
додано

Перевірте запит, якщо встановлено заголовок діапазону HTTP, клієнт завантажує файл на частини, він хоче завантажити лише невелику частину даних відразу (наприклад: Діапазон: байт = 500-999). Зазвичай це здійснюється веб-сервером автоматично, але в цьому випадку вам доведеться обробляти його і відправити лише потрібний діапазон. Зберігайте хід сеансу і забороняйте доступ лише в тому випадку, якщо клієнт завантажив усі фрагменти.

0
додано

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

0
додано
Ukrainian PHP comunity
Ukrainian PHP comunity
885 учасників

dev-ua/php