2009-09-17 2 views
3

Я пытаюсь использовать следующий код, чтобы создать почтовый файл из каталога и служить его пользователю через HTTP загрузки:Создание и обслуживание сжатых файлов с PHP

// 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 снова .. и так далее.

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

Спасибо!

+2

Ваш тип пантомимы приложения/октет потока не является неверной, но это может быть дружелюбнее использовать приложение/почтовый индекс. –

+0

@ Тони Миллер - почему бы не поставить это как ответ? Здесь может быть проблема. – karim79

+0

Как сделать «на лету zipping и streaming» от php: http: // stackoverflow.com/a/4357904/416630 – Lee

ответ

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

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

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

+0

Теперь я указываю заголовок Content-Length, и он все еще не работает. Я просто стараюсь одновременно обслуживать около 15 небольших файлов, и я понял, что zipping - мой единственный вариант. Есть ли другой способ сделать это? –

1

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

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

+1

Хорошо, я попытался изменить тип MIME на application/zip, а также на жесткое кодирование в zip-файле, который, как я знал, был хорошо сформирован (файл, который распакован как на моем компьютере, так и на сервере после загрузки) и получил тот же результат. –

0

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

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

+0

Хорошо, я пробовал использовать приложение/zip без везения. Диалог загрузки браузера указывает мне, что я пытаюсь загрузить «архив ПК ZIP», и когда он загружается на мою машину, OS X показывает «Kind: ZIP Archive», но он делает то же самое, когда я пытаюсь разархивировать его. (Это также с жестко закодированным файлом, который я не застегивал на лету, который работал на моей машине перед загрузкой) –

8

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

решаемые с помощью ob_clean и флеш-ФУНКЦИИ

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"); 
Смежные вопросы