Intereting Posts
Изменение текущего часового пояса пользователя на основе смещения UTC сервера и смещения UTC пользователя Какова наилучшая практика для системы входа на основе ролей в Codeigniter отправка пользователю mesage путем передачи их идентификатора в модальный блок consolibyte quickbooks php для добавления простого xml Содержимое ответа должно быть строкой или объектом, реализующим __toString (), «boolean», заданный после перехода на psql cakephp-маршрутизация без id? Невозможно выбрать Latin-1 как набор символов в PHPMyAdmin Как я могу заставить свой PHP-скрипт работать в определенное время каждый день? Получение размера в памяти объекта в PHP? Исправление ошибок исправления 500 Публичные функции и функции в CodeIgniter Предупреждение: mysql_fetch_array () ожидает, что параметр 1 будет ресурсом, boolean given AJAX внутри цикла foreach Как CodeIgniter сохраняет данные сеанса даже при закрытии браузера? Обрезаемая фатальная ошибка: объект класса mysqli_stmt не может быть преобразован в строку

Определение успешной загрузки с использованием файла чтения php

Мне нужно знать, выбрал ли пользователь загрузку, затем нажал кнопку отмены, что не совпадает с файлом чтения с ошибкой. Я проверил счет, возвращаемый функцией readfile, но он показывает байты в файле, даже если пользователь отменил загрузку в диалоговом окне «Сохранить как».

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

Это касается защиты интеллектуальной собственности, так как файлы являются собственностью члена, который их загрузил, и мне нужно сохранить контрольный след того, что другие участники загружали файл, если они начнут плавать в Интернете. Но если функция readfile всегда отражает размер файла (что означает, что эти байты были переданы каким-то образом), я не знаю, действительно ли был загружен файл.

Я видел несколько сообщений по этому вопросу, но никаких реальных решений о том, что должно быть частым потреблением, – они загрузили его или нет? Просто зная, что они нажали кнопку загрузки, на самом деле не говорят, решили ли они пройти с ним, поскольку диалоговое окно «Сохранить как» позволяет кому-то отменить фактическое завершение загрузки.

Для полноты, вот мой код загрузки до функции readfile:

header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header("Content-Disposition: attachment; filename=$download_name"); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize("sub/$doc_file")); ob_clean(); flush(); $wasdownloaded = readfile("sub/$doc_file"); 

Я боюсь, что правильный ответ «Невозможно» – позвольте мне объяснить: вы могли бы правильно определить, когда файл пересек провод, но вы не можете надежно определить, отбрасывал ли клиент его или нет.

Пример (хронологическая последовательность):

  • Пользователь загружает MSIE и получает диалог «Сохранить где».
  • Пока этот диалог открыт, загрузка начинается в фоновом режиме.
  • Пользователь перемещается в диалоговом окне или просто ничего не делает (телефон зазвонил, он говорит)
  • Загрузка фонового изображения завершена, ваш скрипт видит, что загрузка завершена
  • Пользователь нажимает кнопку «отменить»,
  • MSIE удаляет временный файл, загрузка никогда не сохраняется в доступной для пользователя форме

Результат:

  • Пользователь видит файл как «не загружен» – и он прав
  • Ваше приложение видит файл как «правильно загруженный» – и это правильно

Сначала вам нужно ignore_user_abort () .

Это позволит вашему скрипту продолжить работу после того, как пользователь ударит отмену или сбежит.

Затем вам придется print файл и постоянно проверять с помощью connection_aborted () .

 header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header("Content-Disposition: attachment; filename=$download_name"); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize("sub/$doc_file")); ob_clean(); flush(); $fp=fopen("sub/$doc_file","rb"); while(!feof($fp)) { print(fread($fp,1024*8)); flush(); ob_flush(); if( connection_aborted() ) { //do code for handling aborts } } в header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header("Content-Disposition: attachment; filename=$download_name"); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize("sub/$doc_file")); ob_clean(); flush(); $fp=fopen("sub/$doc_file","rb"); while(!feof($fp)) { print(fread($fp,1024*8)); flush(); ob_flush(); if( connection_aborted() ) { //do code for handling aborts } } 

Используйте этот комментарий на php.net: http://www.php.net/manual/en/function.fread.php#72716 В fclose вы сможете определить, был ли файл загружен успешным, потому что вы проверяете, прерывание соединения с connection_status()