Генерация zip-файлов с PHP + Apache на лету в высокой скорости?

У меня есть еще один взлом для людей, которые все еще заинтересованы:

<i class="fa fa-chevron-circle-up fa_with_bg"></i>

И CSS:

.fa_with_bg{
    position: relative;
}

.fa_with_bg::after{
    position: absolute;
    content: '';
    background: #fff;
    z-index: -1;
    top: 10px;
    left: 3px;
    width: 35px;
    height: 33px;
}

Вам просто нужно добавить класс fa_with_bg к нему.
* Возможно, вам придется немного поиграть со свойствами top, left, width и height.

9
задан Vilx- 13 June 2009 в 11:43
поделиться

4 ответа

Это может быть то, что вам нужно: http://pablotron.org/software/zipstream-php/

Эта библиотека позволяет создавать zip-файл с динамической потоковой передачей без переключения на диск.

9
ответ дан 4 December 2019 в 19:35
поделиться

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

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

Для поддержки возобновления вам необходимо проверить значение $ _SERVER ['HTTP_RANGE'], его формат подробно описан здесь и один раз вы поняли, что вам нужно запустить что-то вроде этого.

$size = filesize($zip_file);

if(isset($_SERVER['HTTP_RANGE'])) {
    //parse http_range
    $range = explode( '-', $seek_range);
    $new_length = $range[1] - $range[0]
    header("HTTP/1.1 206 Partial Content");
    header("Content-Length: $new_length");
    header("Content-Range: bytes {$range[0]}-$range[1]");
    echo file_get_contents($zip_file, FILE_BINARY, null, $range[0], $new_length);
} else {
    header("Content-Range: bytes 0-$size");
    header("Content-Length: ".$size);
    echo file_get_contents($zip_file);
} 

Это очень схематичный код, вам, вероятно, придется немного поиграть с заголовками и содержимым переменной HTTP_RANGE. Вы можете использовать fopen и fwrite вместо содержимого file_get, если хотите, и просто переходите в нужное место.

Теперь к вашим вопросам.

  • PHP имеет тайм-аут выполнения для скриптов. Хотя он может быть изменен самим сценарием, не возникнет ли проблем при его полном удалении?

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

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

Кэшируйте файл на жесткий диск, значит, у вас не будет этой проблемы.

  • Не будет ли передача больших объемов файловых данных через PHP сама по себе снижением производительности?

Да, не будет. так же быстро, как обычная загрузка с веб-сервера. Но это не должно быть слишком медленным.

1
ответ дан 4 December 2019 в 19:35
поделиться

Используйте, например, библиотеку PhpConcept Library Zip .

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

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

1
ответ дан 4 December 2019 в 19:35
поделиться

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

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

Я иду еще дальше, я генерирую одну контрольную сумму из всех crc входного файла и использую ее как электронный тег для сгенерированного файла для поддержки кэширования и как часть имени файла. Если вы уже загрузили сгенерированный zip-файл, браузер получит его из локального кеша, а не с сервера. Вы также можете настроить скорость загрузки (например, 300 КБ / с). Можно делать zip-комментарии. Вы можете выбрать, какие файлы можно добавлять, а какие нет (например, thumbs.db).

Но есть одна проблема, которую вы не можете полностью решить с помощью формата zip. Это генерация значений crc. Даже если вы используете хэш-файл для решения проблемы с памятью или используете hash-update для постепенного создания crc, он будет использовать много ресурсов процессора. Немного для одного человека, но не рекомендуется для профессионального использования. Я решил это с помощью дополнительной таблицы значений crc, которую я генерирую с помощью дополнительного скрипта. Я добавляю эти значения crc для каждого параметра в класс zip. При этом класс очень быстрый. Как вы упомянули, как обычный сценарий загрузки.

Мой класс zip находится в разработке, вы можете посмотреть его здесь: http://www.ranma.tv/zip-class.txt

Я надеюсь, что смогу помочь кому-нибудь с этим :)

Но я прекращу этот подход, я перепрограммирую свой класс на класс tar. С tar мне не нужно генерировать значения crc из файлов, tar нужны только контрольные суммы для заголовков, вот и все. И мне больше не нужна дополнительная таблица mysql. Я думаю, что это упрощает использование класса, если вам не нужно создавать для него дополнительную таблицу crc. Это не так сложно, потому что файловая структура tars проще, чем структура zip.

PHP имеет таймаут выполнения для скриптов. Хотя он может быть изменен самим сценарием, не возникнет ли проблем при его полном удалении?

Если ваш сценарий безопасен и закрывается при прерывании пользователем, вы можете удалить его полностью. Но будет безопаснее, если вы просто обновите тайм-аут для каждого файла, который вы просматриваете:)

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

Да, это сработает. Я создал контрольную сумму из входного файла crc's. Я использовал это как электронный тег и как часть имени файла zip-архива. Если что-то изменилось, пользователь не сможет возобновить созданный zip-архив, потому что электронный тег и имя файла изменились вместе с содержимым.

Не будет ли передача больших объемов файловых данных через PHP сама по себе снижением производительности?

Нет, если вы только пропустите, он не будет использовать намного больше, чем обычная загрузка. Может 0,01% не знаю, это немного :) Я предполагаю, потому что php мало что делает с данными :)

1
ответ дан 4 December 2019 в 19:35
поделиться
Другие вопросы по тегам:

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