Создайте zip-файл, но предоставляйте его как загрузку без сохранения на сервере [duplicate]

Неглубокое клонирование коллекции легко, но если вы хотите использовать глубокий клон, библиотека, вероятно, сделает вас лучше, чем ручное кодирование (так как вы хотите клонировать элементы внутри в коллекции) .

Так же, как этот ответ , я использовал библиотеку Cloner и, в частности, протестировал его против XStream (который может «клонировать» путем сериализации десериализация) и двоичной сериализации. Хотя XStream очень быстро выполняет сериализацию в / из xml, Cloner намного быстрее при клонировании:

0.0851 ms: xstream (клонирование путем сериализации / десериализации) 0.0223 ms: двоичная сериализация (клонирование путем сериализации / десериализации) 0.0017 ms: cloner * среднее время клонирования простого объекта (два поля) и стандартного конструктора public. Выполняйте 10 000 раз.

В дополнение к быстрому, здесь больше причин выбирать клонирование:

  1. выполняет глубокий клон любого объекта (даже те, которые вы не записывайте себя)
  2. вам не нужно постоянно обновлять метод clone () каждый раз, когда вы добавляете поле
  3. , вы можете клонировать объекты, t имеет стандартный конструктор по умолчанию
  4. работает с Spring
  5. (оптимизация) не клонирует известные неизменяемые объекты (например, Integer, String и т. д.)
  6. easy использовать. Пример: cloner.deepClone (anyObject);

26
задан ralokt 27 July 2009 в 17:01
поделиться

5 ответов

У меня была одна и та же проблема, но в конце концов я нашел несколько неясное решение и решил поделиться им здесь.

Я пришел по большим сценариям zip.lib.php / unzip.lib.php, которые поставляются с phpmyadmin и являются расположенный в каталоге «libraries».

Использование zip.lib.php работало как прелесть для меня:

require_once(LIBS_DIR . 'zip.lib.php');

... 

//create the zip
$zip = new zipfile();

//add files to the zip, passing file contents, not actual files
$zip->addFile($file_content, $file_name);

...

//prepare the proper content type
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=my_archive.zip");
header("Content-Description: Files of an applicant");

//get the zip content and send it back to the browser
echo $zip->file();

Этот скрипт позволяет загружать почтовый индекс без необходимости иметь файлы как реальные файлы или сохранение самого zip в качестве файла.

Позор, что эта функциональность не является частью более общей библиотеки PHP.

Вот ссылка на zip.lib.php из источника phpmyadmin: https://github.com/phpmyadmin/phpmyadmin/blob/RELEASE_4_5_5_1/libraries/zip.lib.php

UPDATE: убедитесь, что вы удалили следующую проверку с начала zip.lib.php, иначе скрипт просто завершится:

if (! defined('PHPMYADMIN')) {
    exit;
}

UPDATE: этот код доступен и для проекта CodeIgniter : https://github.com/patricksavalle/CodeIgniter/blob/439ac3a87a448ae6c2cbae0890c9f672efcae32d/system/ хелперы / zip_helper.php

43
ответ дан Samuel Reid 23 August 2018 в 16:39
поделиться
  • 1
    Вы должны упомянуть, что вам нужно изменить его, чтобы удалить проверку для определения константы «PHPMYADMIN», или она просто закончит сценарий. Мне потребовалось больше секунды, чтобы справиться с этим. – Nathaniel 19 May 2013 в 04:44
  • 2
    Спасибо, кажется, проверка была введена после того, как я опубликовал вышеупомянутый ответ. Я обновил ответ. – nettle 20 May 2013 в 16:09
  • 3
    Работает как шарм. Я сделал это в помощнике Codeigniter без каких-либо проблем. – Patrick Savalle 27 August 2014 в 14:03
  • 4
    Я создал помощник Codeigniter с этим кодом. Работает на меня. Вот он: github.com/patricksavalle/CodeIgniter/blob/… – Patrick Savalle 27 August 2014 в 14:31
  • 5
    Спасибо! он работает на GAE – igonejack 3 April 2015 в 01:08

Что касается вашего комментария о том, что php: // temp работает для вас, за исключением случаев, когда вы его закрываете, попробуйте оставить его открытым, очистить вывод, а затем перемотать обратно на 0 и прочитать его.

Посмотрите еще несколько примеров: http://us.php.net/manual/en/function.tmpfile.php

Также исследует выходную буферизацию и захват: http://us.php.net/manual/en/function.ob-start.php

2
ответ дан Chloe 23 August 2018 в 16:39
поделиться

Есть ли проблема производительности здесь, или это просто оскорбляет ваше чувство правильности? Многие процессы записывают временные файлы и удаляют их, и часто они никогда не попадают на диск из-за кэширования.

Временной файл автоматически удаляется при закрытии. Вот в чем его природа.

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

  • использовать ram диск.
  • изменить класс ziparchive, чтобы добавить метод, который делает все, что делает метод close (), за исключением того, что фактически закрывает файл. (Или добавьте параметр отпускания для закрытия ()). Это может быть даже невозможно в зависимости от базовых библиотек C.
-7
ответ дан Lucky 23 August 2018 в 16:39
поделиться

, что вы используете для создания архива? Возможно, вы сможете использовать память потока php: // temp или php: // для чтения и записи в / из архива.

См. http://php.net/manual/ ан / wrappers.php.php

3
ответ дан Tom Haigh 23 August 2018 в 16:39
поделиться
  • 1
    На данный момент я использую расширение php zip и записываю временный файл всякий раз, когда я обслуживаю загрузку. Я попытался использовать php: // temp wrapper (считая, что он превосходит память php: //, как и при большом количестве данных, tempfile - хорошая идея, и хосты могут разрешить его использование даже при ограничении доступа fs. столкнулся с проблемой, что мне пришлось закрыть zip-файл, который явно освободил все в php: // temp /. (Чтение из zip-файла до и после закрытия дало мне 0 байт.) В любом случае, меня не интересует библиотека I конечно, использовать PHP-internal. – ralokt 28 July 2009 в 08:10

Вам нужно использовать ZipArchive::addFromString - если вы используете addFile(), файл фактически не добавляется до тех пор, пока вы не закроете его. (Ужасная ошибка IMHO, если вы пытаетесь переместить файлы в zip, и вы удаляете их, прежде чем закрыть zip ...) Метод addFromString() немедленно добавляет его в архив.

0
ответ дан user35443 23 August 2018 в 16:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: