Мне нужно знать, выбрал ли пользователь загрузку, затем нажал кнопку отмены, что не совпадает с файлом чтения с ошибкой. Я проверил счет, возвращаемый функцией 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");
Я боюсь, что правильный ответ «Невозможно» – позвольте мне объяснить: вы могли бы правильно определить, когда файл пересек провод, но вы не можете надежно определить, отбрасывал ли клиент его или нет.
Пример (хронологическая последовательность):
Результат:
Сначала вам нужно 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()