PHP: проблема с использованием passthru для потоковой передачи zip только на mac os x

Я пытаюсь собрать решение для потоковой передачи zip с помощью команды zip Unix и функции passthru PHP, но я столкнулся с проблемой.

Скрипт выглядит примерно так:

<?php
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachement; filename=myfile.zip");
passthru("zip -r -0 - /stuff/to/zip/");
exit();
?>

Команда zip работает нормально, и браузер получает вывод и сохраняет его в виде zip-файла. Затем ZIP-файл можно нормально распаковать в Windows и Unix, но в Mac OS X встроенный экстрактор (BOMArchiveHelper) не может извлечь файл. Однако использование других приложений в OS X работает нормально.

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

Изучив zip-архив, я обнаружил, что файл, созданный файлами PHP, на несколько байтов больше, чем файл, созданный непосредственно командой zip на сервере. Кажется, что потоковой процесс с passthru добавляет что-то в файл, что, вероятно, вызывает проблемы с BOMArchiveHelper.

Чтобы проверить это, я использовал passthru для потоковой передачи zip-файла, который я уже создал на сервере: passthru("cat stuff.zip") Это прекрасно работало с BOMArchiveHelper.

Таким образом, проблема, похоже, кроется где-то в процессе, когда функция passthru берет двоичные данные, сгенерированные на лету командой zip, и передает их в браузер.

Я пытался удалить все источники, из которых могли генерироваться лишние байты (устанавливая команду zip на тишину и т. д.), но добавленные данные все еще остаются. Бинарное сравнение потокового zip-архива и предварительно сгенерированного zip-архива показывает, что дополнительные данные разбросаны по всему zip-архиву, а не только в конце или начале.

Кто-нибудь знает или видел эту проблему раньше и решил, что ее невозможно решить?

NB: поскольку кто-то уже столкнулся и очень хорошо описал эту проблему до меня без какого-либо ответа, я просто скопировал / вставил его сообщение сюда и убедился, что все его тесты действительно провалились, и ни один из моих не прошел...

По-видимому, единственный способ заставить это работать - попросить людей использовать либо распаковку, либо расширение суффикса...


person Julien P.    schedule 23.08.2010    source источник
comment
Вы неправильно написали вложение в заголовке, но похоже, что ваша проблема связана с командой zip, а не с PHP.   -  person Inigoesdr    schedule 23.08.2010
comment
Я не уверен, что это связано с командой zip... потому что, когда я запускаю команду вне функции passthru, она отображает zip-файл, который я могу открыть на своем Mac...   -  person Julien P.    schedule 07.09.2010
comment
И извините, что не ответил раньше, но я не получил никакого уведомления от stackoverflow.   -  person Julien P.    schedule 07.09.2010


Ответы (1)


Если вы используете nginx, взгляните на http://wiki.nginx.org/NginxNgxZip.

person Steffen    schedule 11.09.2010
comment
Очень красиво, мне это очень нравится. В настоящее время я использую Apache2, но обязательно попробую. Мне также нужно убедиться, что он не будет хранить zip на диске, потому что мне нужно что-то, что сразу же передает его, добавляя файл в zip динамически, без сохранения всего файла на сервере, как это делают многие другие zipOnTheFlyScripts. Я дам вам знать, как идут дела! Спасибо - person Julien P.; 11.09.2010
comment
Вот (stackoverflow.com/a/4357904/416630) решение, которое будет работать с apache (и должно работать с любым другой веб-сервер тоже) - person Lee; 23.11.2012