У меня есть .zip-файл, который создается на сервере с помощью php. Созданный файл действителен, и я проверил его, загрузив его через ftp и т. Д.
Мне нужно создать способ для пользователя загрузить этот файл после его создания, а затем файл будет удален. Вот заголовки, которые я отправляю.
header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-control: public"); header("Content-Description: File Transfer"); header('Content-type: application/zip'); header("Content-Transfer-Encoding: Binary"); header('Content-Disposition: attachment; filename="'.basename($archive_file_name).'"'); header("Content-Length: " . filesize($this->dirPath."/".$archive_file_name) ); ob_clean(); //echo is_file($this->dirPath."/".$archive_file_name); readfile($this->dirPath."/".$archive_file_name); unlink($this->dirPath."/".$archive_file_name); exit;
Код выше работает, когда я пытаюсь загрузить первые несколько раз, но после нескольких поворотов он начинает загружаться как .php-файл вместо .zip
Загрузка файла запускается путем перехода к определенной ссылке, которая запускает создание zip-файла. Как только это будет сделано, он отправит заголовки, чтобы начать загрузку
ваш код выглядит правильно. Однако вам необходимо обеспечить предыдущие и последующие пробелы для вашего кода.
при добавлении заголовков в ваш код, пространство будет нарушено и не будет загружать zip-файл.
Проверьте еще раз и удалите пробелы сверху и снизу страницы.
И строка, которая гласит:
ReadFile ($ this-> dirPath "/" $ archive_file_name..);
может быть удалена из кода
попробуйте этот заголовок, доступный вам для загрузки с резюме. Я предлагаю использовать базу данных или файл журнала для понимания загруженного файла или нет, потому что этот заголовок доступен загрузчик для загрузки частичной части
получить диапазон запросов от загрузчика, вы можете использовать fseek для чтения диапазона файлов
$Range=@$_SERVER['HTTP_RANGE'];//Range: bytes=843530240- $Cach=""; if($Range!=""){ $Range=explode("=",$Range); $Cach=(int)trim($Range[1]," -"); }
контроллер кеширования
function caching_include($file) { $headers = $_SERVER; // Get the modification timestamp if(!(list(,,,,,,,,,$lastModified) = @stat($file))){ echo Error; exit(); } // Build our entity tag $eTag = "ci-".dechex(crc32($file.$lastModified)); if (false and (strpos(@$headers['If-None-Match'], "$eTag")) &&(gmstrftime("%a, %d %b %Y %T %Z", $lastModified) == @$headers['If-Modified-Since'])) { // They already have an up to date copy so tell them header('HTTP/1.1 304 Not Modified'); header('Cache-Control: private'); header("Pragma: "); header('Expires: '); header('Content-Type: '); header('ETag: "'.$eTag.'"'); exit; } else { // We have to send them the whole page header('Cache-Control: private'); header('Pragma: '); header('Expires: '); header('Last-Modified: '.gmstrftime("%a, %d %b %Y %T %Z",$lastModified)); header('ETag: "'.$eTag.'"'); } }
Заголовок для загрузки
header("Server: SepidarSoft/ir-system");//server name header("Date: ".date("a,db YH:M:S GMT",time())); header("X-Powered-By: SepidarSoft"); header("Cache-Control: public"); header("Content-disposition:filename=\"".$BaseName."\"");//file name caching_include($FPatch);//caching controller header("Accept-Ranges:bytes"); header("Content-Transfer-Encoding: binary\n"); header("Connection: Keep-Alive"); header("Content-Type: $Type");//file type like application/zip header("Content-Length: ".($FSize-$Cach)); //length of download it is for resume header("Content-Range: bytes ".$Cach."-".($FSize-1)."/".$FSize); //download range it is for resume header("HTTP/1.1 206 Partial Content",true); set_time_limit(0);
если используется set_time_limit(0);
в коде, если пользовательское соединение перестает работать, до завершения работы, так как ваш файл будет удаляться или нет после одного запроса, вы можете использовать connection_status()==0
для проверки соединения, как показано ниже
$Speed=102400; fseek($Handle,$From);//if use resume it is useful while(!@feof($Handle) and (connection_status()==0)){ print(fread($Handle,$Speed)); flush(); ob_flush(); } if(connection_status()==0){//with this condition you can understand download is down by user unlink($this->dirPath."/".$archive_file_name); }