Большие возможности маленького сайта (Работа с Zip архивами)

Автор статьи: Феськов Кузьма
Сайт Автора: php.russofile.ru
E-mail Автора: kuzma@russofile.ru
Дата публикации: 26.04.2006


И так, начнем...

Не так давно я разрабатывал систему тестов, тесты хранились в отдельных XML файлах и каждый тест занимал незначительный объем – в пределах килобайта. Как вы понимаете, файлов было неисчислимое множество. Уже на этапе разработки мы насчитывали несколько тысяч тестов. Все это хоть и было структурировано, но лежало в каталогах по 1000 файлов в каждом. Работать с этим было тяжело, как вы понимаете, маленькие файлы занимают места часто больше, чем свой реальный размер...

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

Для разработки своей системы ресурсов я использовал архив формата ZIP и библиотеку PCLZip (http://www.phpconcept.net/pclzip/). Почему? Ну, во-первых, PHP очень хорошо умеет работать с такими архивами, а, во-вторых, алгоритм сжатия ZIP достаточно прост, чтобы загружать процессор в незначительной степени (в конечном итоге, мы вообще можем не сжимать файлы, а просто собирать их в один архив для удобства). Также, нам понадобится библиотека zlib (http://www.gzip.org/zlib/).

Давайте подготовим с вами архив ZIP, я, например, собрал в один архив те самые 1000 файлов из каталога, для эксперимента поставил самую высокую степень сжатия. Размер дискового пространства в значительной степени увеличился :-) А заодно у нас появился 1 файл вместо 1000.

Далее, скачиваем, указанную выше, библиотеку и копируем ее в нужный вам каталог.

Сначала давайте научимся находить в каком из архивов у нас нужный файл. Архивы у нас называются числами вида 0000.zip, 0001.zip, .... и так далее. Как я уже говорил, в каждом архиве у нас 1000 файлов. Вычисляем все очень просто. Берем ID теста из базы и ищем по нему номер архива:

$arch = substr(intval($ID / 1000) + 10000, 1, 4) . ‘.zip’;

В результате в переменной $arch у нас находится название нужного нам архива. Нужный нам файл в архиве будет называться $ID.xml.

Теперь нам остается достать нужный файл из архива:

// Подключаем библиотеку PCL Zip
require_once('pclzip.lib.php');

// Создаем объект $zip. В качестве параметра передаем имя архива.
$zip = new PclZip($arch);

// Извлекаем нужным нам файл в переменную
$content = $zip->extract(PCLZIP_OPT_BY_NAME, $ID . '.xml',
                         PCLZIP_OPT_EXTRACT_AS_STRING);

// Получаем содержимое файла
$content = $content[0]['content'];

Теперь переменная $content содержит текст нужного нам файла.

Я рекомендую вам ТОЛЬКО ИЗВЛЕКАТЬ данные из архива, но не добавлять их туда и не изменять архива. Поскольку эти действия значительно более затратные по сравнению с извлечением.

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

Далее, я опишу все функции библиотеки PCLZip.