Создание и обслуживание zip-файлов с помощью php

Я пытаюсь использовать следующий код для создания zip-файла из каталога и подавать его пользователю через http-загрузку:

// write the file file_put_contents($path . "/index.html", $output); // zip up the contents chdir($path); exec("zip -r {$course->name} ./"); $filename = "{$course->name}.zip"; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' .urlencode($filename)); header('Content-Transfer-Encoding: binary'); readfile($filename); 

Я могу создать zip-файл, но загрузка его по http не работает. Если я загружаю zip-файл, созданный с помощью ftp-клиента, то Stuffit Expander от Mac распаковывает файлы просто отлично, но если я загружу его через http, mac unzipper создаст бесконечный цикл. Я имею в виду, что файл, который я загружаю, называется course.zip, а затем распаковка файла дает course.zip.cpgz и распаковку этого файла дает course.zip снова .. и так далее.

У кого-нибудь есть идеи?

Благодаря!

Related of "Создание и обслуживание zip-файлов с помощью php"

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

  2. Если это изменчивый файл или только один небольшой файл, который вы хотите передать сжатым, попробуйте вместо этого использовать ob_start('ob_gzhandler') , проще, меньше, чище. Файл передается сжатым, но он сохраняется в исходном формате на стороне клиента.

  3. Указание заголовка Content-Length необходимо, чтобы позволить загрузчику знать конец файла, позволяя контролировать прогресс, обнаруживать повреждение файла и избегать зависания сеанса HTTP (если соединение находится в режиме Keep-Alive), возможно недостаток этого заголовка является корнем проблемы.

У меня была эта проблема, и оказалось, что загруженный zip-файл имел новую строку, вставленную в самом начале.

Решено использовать функции ob_clean и flush

  header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".basename($archive_file_name)); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($archive_file_name)); ob_clean(); flush(); echo readfile("$archive_file_name"); 

Как было предложено karim79 , я поместил свой комментарий в качестве ответа: что произойдет, если вы измените тип MIME из приложения / октетного потока в application / zip?

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

Что вы видите, так это то, что утилита архива не распознает zip-файл в виде zip-файла и пытается застегнуть ZIP-архив. Вторая операция просто распаковывает первый созданный файл, поэтому никогда не открывайте файл вообще. Это связано с повреждением почтового индекса.

Возможно, браузер в какой-то момент искал zip-файл (преобразование новой строки?) Во время процесса загрузки. Как уже упоминалось, проверьте тип mime и используйте php header (), чтобы установить правильный тип MIME (application / zip).