У меня есть приложение symfony 2.8, и при нажатии пользователем кнопки «загрузить» я использую клавиши нескольких больших (изображений, видео) файлов на s3, чтобы передать это браузеру в виде zip-файла с помощью ZipStream ( https: // github. com / maennchen / ZipStream-PHP ).
Потоковая передача файлов и загрузка в виде zip (хранимых, а не сжатых) удачных в браузере и почтовых сайтах в Downloads. Однако при попытке открыть zip в Mac OSX El Capitan с помощью утилиты архива (встроенное программное обеспечение архива на OSX), он не работает. Ошибка:
Невозможно расширить «test.zip» в «Загрузки». (Ошибка 2 – нет такого файла или каталога.)
Я видел более старые идентичные проблемы в SO и пытался исправить эти исправления, особенно этот пост: https://stackoverflow.com/a/5574305/136151 и отслеживал проблемы и PR в ZipStream, которые связаны и восходящие исправления в Guzzle и т. Д. ,
Проблема в том, что вышеупомянутые исправления были в 2011 году, и в это время все происходит. Поэтому, применяя те же исправления, я не получаю рабочий результат.
Конкретные исправления, которые я пробовал: 1. Установка «версия для извлечения» в 0x000A, как было предложено. Также как «20», как рекомендовано в другом посте. Я установил то же самое для «version made by». 2. Я попытался заставить метод сжатия «deflate» вместо «stored», чтобы узнать, получил ли я рабочий результат. Сохраненный результат – все, что мне нужно, и подходит для почтового индекса, используемого в качестве файла контейнера для изображений и видео.
Я могу извлечь zip, используя стороннее приложение архива, которое называется The Unarchiver. Тем не менее, пользователи не будут знать и не могут ожидать установки альтернативного приложения для архивации в соответствии с моим веб-приложением. Это не эффективное решение.
Кто-нибудь имеет знания или опыт решения этой проблемы и может помочь мне решить, как ее решить?
NB: Необходимым решением является потоковая почта в браузере. Загрузка активов с s3 на сервер для создания zip-файла, а затем поток полученного zip-браузера не является решением, учитывая количество времени и накладных расходов на такой подход.
Добавлена информация, если требуется:
Код и настройка: – Файлы хранятся на s3. – Веб-приложение – symfony 2.8 на PHP7.0, запускающееся на ec2 с Ubuntu. – Используя aws-sdk-php, создайте s3client с действительными учетными данными, и я зарегистрирую StreamWrapper (s3client-> registerStreamWrapper ()) на s3client. Это для получения файлов из s3 через fopen to stream в библиотеку ZipStream:
$this->s3Client = $s3Client; $this->s3Client->registerStreamWrapper(); // Initialize the ZipStream object and pass in the file name which // will be what is sent in the content-disposition header. // This is the name of the file which will be sent to the client. // Define suitable options for ZipStream Archive. $opt = array( 'comment' => 'test zip file.', 'content_type' => 'application/octet-stream' ); $zip = new ZipStream\ZipStream($filename, $opt); $keys = array( "zipsimpletestfolder/file1.txt" ); foreach ($keys as $key) { // Get the file name in S3 key so we can save it to the zip file // using the same name. $fileName = basename($key); $bucket = 'mg-test'; $s3path = "s3://" . $bucket . "/" . $key; if ($streamRead = fopen($s3path, 'r')) { $zip->addFileFromStream($fileName, $streamRead); } else { die('Could not open stream for reading'); } } $zip->finish();
Результаты вывода Zip:
Извлечение на mac через утилиту архива завершается с ошибкой 2
Экстракция на mac с Unarchiver работает.
Экстракция на окна с 7-zip-работами.
Извлечение окон с WinRar не удается – говорит, что почтовый индекс поврежден.
Заголовки ответов:
Изменить. Я открыт для использования другого метода потоковой передачи файлов в браузер в виде zip, который можно открыть на Mac, Windows, Linux изначально без использования ZipStream, если это предлагается. Просто не создавайте сторону сервера файлов zip для последующего потока после этого.
Проблема с загруженным zip заключается в том, что он содержал html из ответа в контроллере Symfony, который вызывал ZipStream-> addFileFromStream (). В основном, когда ZipStream транслировал данные для создания zip-загрузки в клиентском браузере, также был отправлен ответ на действие контроллера, и, что лучше всего предположить, эти два путались в браузере клиента. Открытие zip-файла в шестнадцатеричном редакторе и просмотр html там, очевидно, было проблемой.
Чтобы заставить это работать в Symfony 2.8 с ZipStream, я просто использовал StreamedResponse Symfony в действии контроллера и использовал ZipStream в функции streamedResponse. Для потоковой передачи файлов S3 я просто передал массив s3keys и s3client в эту функцию. Так:
use Symfony\Component\HttpFoundation\StreamedResponse; use Aws\S3\S3Client; use ZipStream; //... /** * @Route("/zipstream", name="zipstream") */ public function zipStreamAction() { //test file on s3 $s3keys = array( "ziptestfolder/file1.txt" ); $s3Client = $this->get('app.amazon.s3'); //s3client service $s3Client->registerStreamWrapper(); //required $response = new StreamedResponse(function() use($s3keys, $s3Client) { // Define suitable options for ZipStream Archive. $opt = array( 'comment' => 'test zip file.', 'content_type' => 'application/octet-stream' ); //initialise zipstream with output zip filename and options. $zip = new ZipStream\ZipStream('test.zip', $opt); //loop keys useful for multiple files foreach ($s3keys as $key) { // Get the file name in S3 key so we can save it to the zip //file using the same name. $fileName = basename($key); //concatenate s3path. $bucket = 'bucketname'; $s3path = "s3://" . $bucket . "/" . $key; //addFileFromStream if ($streamRead = fopen($s3path, 'r')) { $zip->addFileFromStream($fileName, $streamRead); } else { die('Could not open stream for reading'); } } $zip->finish(); }); return $response; }
Решаемые. Возможно, это помогает кому-то другому использовать ZipStream в Symfony.