Главные новости

Работа с Zip архивами через PHP

Работа с Zip архивами через PHP
Рассказ будет о том, как работать с маленьким PHP классом PclZip, в котором всего 5698 строк с комментариями. Как уже можно было догадаться из названия этот класс для работы с Zip архивами. Я в сжатой форме познакомлю вас с данным классом. 

 
1. Создание архива с нуля


Для создания архива с нуля пишем:

<?php
include_once(‘pclzip.lib.html’); //Подключаем библиотеку.
$archive = new PclZip('archive.zip'); //Создаём объект и в качестве аргумента, указываем название архива, с которым работаем.
$result = $archive->create('file.txt'); // Этим методом класса мы создаём архив с заданным выше названием 
var_dump($result); // Если всё прошло хорошо, возращаем массив с данными (время создание архива, занесённым файлом и т.д)
if($result == 0) {
echo $archive->errorInfo(true); //Возращает причину ошибки

?>

Но если вам надо заархивировать например файл file.txt, который лежит в папке folder и надо сделать так, чтобы file.txt лежал в корне архива, а не полность папка folder с file.txt, можно сделать так
<? 
$result = $archive->create('folder/file.txt', PCLZIP_OPT_REMOVE_PATH, 'folder');
?>

Если надо взять файл из одной папки и переместить его в архиве в другую папку, пишем
<?
$result = $archive->create('folder/file.txt', PCLZIP_OPT_REMOVE_PATH, 'folder', PCLZIP_OPT_ADD_PATH, 'install');
?>


То есть мы взяли файл file.txt в папке folder, вытащили и поместили в архиве в папку install. 
Для добавления комметария к архиву надо добавить к create PCLZIP_OPT_COMMENT, ‘Комментарий’.
 
2. Добавление файлов в архив.


Здесь практически всё тоже самое, что и при создании архива с 0.
<?php
include_once(‘pclzip.lib.html’); 
$archive = new PclZip('archive.zip'); //Указываем существующий архив
if($archive->add('file.txt') == 0) echo $archive->errorInfo(true); 
?>


Метод add тоже может использовать PCLZIP_OPT_REMOVE_PATH и PCLZIP_OPT_ADD_PATH, что логично.
 
3. Вывод содержимого архива

Для этой операции у нас в наличии есть метод listContent(). По сути этот метод возращает ту же информацию, что и предыдущие два метода, после заверщения их работы.
<?
$archive = new PclZip('archive.zip');
$result = $archive->listContent();
if ($result == 0) { //Возращает 0, если операция не удалась.
echo $archive->errorInfo(true); //Вывод ошибки.
} else {
foreach($result as $id=> $v1) { // перебор массива с файлами. В переменную $id попадает индекс файла в архиве, который пригодится нам далее, а переменная $v1 становится массивом с данными о файле.
foreach($v1 as $kk=>$v2) { // перебор массива с информацией о файле в архиве
echo "$kk - $v2 ";
}
}
}
?>

 
4. Удаление файлов из архива

Для удаление всех файлов из архива прибегним к методу
<?
$archive = new PclZip('archive.zip');
$result = $archive->delete();
if($result == 0) echo $archive->errorInfo(true); 
?> 

После этого архив останется просто пустой оболочкой. Для удаления одиночных файлов, нам надо сделать так:
<?
$archive->delete(PCLZIP_OPT_BY_INDEX, '1,2');
?>

Этим самым мы указываем, какие файлы удалять. Мы указываем через запятую индификатор файла, которого мы хотим удалить. Индификаторы мы можем получить через функцию, которая рассматривалась выше (listContent).
 
5. Разархивирование

<?
$archive = new PclZip('archive.zip');
$result = $archive->extract();
if($result == 0) echo $archive->errorInfo(true); 
?>

В этом случае будет разархивирован весь архив. Для разархивации в папку делаем так.
<?
$result = $archive->extract(PCLZIP_OPT_PATH, 'folder');
?>


Вот и всё. Это была обзорная статья и она раскрыла не все возможности данного класса, но то что описано здесь, достаточно для обычного использования. Ах да, если заменить zip на rar, то тоже будет всё нормально работать.

 

PCLZip Руководство пользователя (v2.1)


PCLZip – это библиотека для создания и работы с архивами формата ZIP.
Библиотека определяет класс. Копия класса определяет только один архив. Методы, описываемые в этом руководстве, позволяют управлять заданным архивом.
Обратите внимание, публичные методы будут работать всегда (поддерживаться из версии в версию), модификации будут описаны в документации. Частные (внутренние) методы могут быть изменены без предупреждения и не должны использоваться при работе.
PCLZip находится в одном файле (pclzip.lib.html) – это все, что требуется, чтобы иметь весь арсенал библиотеки.

Понимание: как это работает?

Внутреннее представление архива.


Каждый архив PKZIP представлен объектом класса PCLZip. При создании объекта PCLZip (в объекте класса), имя архива ассоциируется с объектом. На данном этапе файл не читается и не проверяется, более того,он может даже не существовать.


<?php
require_once('pclzip.lib.html');
$archive = new PclZip("archive.zip");
?>

Архив управляется публичными методами библиотеки PCLZip. Для создания архива, если он еще не существует, необходимо использовать метод 'create();' со списком файлов и/или папок как параметр.
Если архив уже существует, его содержание может читаться методами доступа, такими, как: 'listContent();' или 'extract();'.

Параметры и аргументы.


Каждый метод имеет свои параметры и аргументы, которые есть в описании метода. Эти аргументы могут быть принудительными или дополнительными. Пример:


<?php<?php
require_once('pclzip.lib.html');
$archive = new PclZip('archive.zip');
$v_list = $archive->add('dev/file.txt',
PCLZIP_OPT_REMOVE_PATH, 'dev');
?>

Здесь первый параметр 'dev/file.txt' принудительный, а 'PCLZIP_OPT_REMOVE_PATH, ...' опциональный.
Некоторые методы можно вызывать только с переменным списком дополнительных параметров:


<?php
$list = $archive->extract(PCLZIP_OPT_PATH, "folder",
PCLZIP_OPT_REMOVE_PATH, "data",
PCLZIP_CB_PRE_EXTRACT, "callback_pre_extract",
PCLZIP_CB_POST_EXTRACT, "callback_post_extract");
?>

В этом примере файлы распакованы в каталог 'folder', а папка 'data', имеющаяся в архиве, из архива удалена.
Также, перед извлечением файла из архива вызывалась возвратная функция, назначенная пользователем (здесь, 'callback_pre_extract();'). Эта функция позволяет изменить путь и имя файла, который находится в процессе извлечения или пропустить извлечение этого специфического файла. В конце извлечения вызывается другая функция, которая дает пользователю возможность проделать над файлом какие-то действия перед извлечением следующего.


<?php
$list = $archive->extract(PCLZIP_OPT_PATH, "folder",
PCLZIP_OPT_REMOVE_ALL_PATH);
?>

Здесь файлы извлечены в директорию 'folder', а все запомненные пути файлов удалены, даже если они были отличны. Эта особенность позволяет пользователю не определять точный путь для удаления.
Эти небольшие примеры показывают работу списка переменных. Они предлагают более точную работу (хотя и добавляют немного сложности). Они так же позволяют вводить новые возможности, не изменяя синтаксиса всех методов.
Все аргументы, их использование и ограничения описаны в разделе “Дополнительные переменные параметры”. В описании функций перечислен список всех доступных дополнительных параметров.

Возвращаемые данные.

Возвращаемые значения могут отличаться от метода к методу. Они описаны в каждом комментарии метода. Однако, большинство методов возвращают 0 при ошибке (и включают флаг ошибки) или массив, описывающий каждый файл при удаче.
Каждый элемент массива описывает файл или папку, некоторые из ее свойств и определение статуса последнего действия с файлом.
Каждый файл описан следующим набором аргументов:


filename
Имя файла
При добавлении – имя, данное файлу при вызове метода.
При извлечении – реальное название извлеченного файла (не название, которое дано этому файлу в архиве).


stored_filename
Название файла в архиве.


size
Реальный размер файла.


compressed_size
Размер сжатого файла (без заголовков).


mtime
Дата и время последней модификации файла (UNIX таймштамп).


сomment
Комментарий сопоставленный с файлом.


folder
true | false: показывает, находится ли файл в папке.


index
Индекс файла в архиве (если задано).


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


status
Результат действия (зависит от типа действия). Значения:

  • ok – положительный результат.
  • Filtered – файл/папка не извлечен (отфильтрован пользователем).
  • already_a_directory – файл не был извлечен, потому что файл или папка с таким же названием уже существует.
  • newer_exist – файл не был извлечен, потому что такой же файл уже существует и защищен от записи.
  • write_protect – файл не был извлечен, потому что существует более новый файл.
  • path_creation_fail – файл не был извлечен – произошла ошибка создания каталога.
  • write_error – файл не был извлечен – произошла ошибка записи.
  • read_error – файл не был извлечен – ошибка чтения.
  • invalid_header – файл не был извлечен – ошибка заголовка.
  • skipped – файл не был извлечен или добавлен, потому что пользовательская функция просит пропустить его.
  • filename_to_long – файл не добавлен в архив – слишком длинное имя файла (максимум 255 символов).

Дополнительные аргументы.

Краткий обзор.

Дополнительные аргументы могут быть разделены на две группы. Первые – классические аргументы, которые дают информацию или инструкции методу. – Вторые – функции возврата, крюки, которые дают пользователю возможность выполнить определенные действия в течении обработки PCLZip. “Функции возврата” сложны для понимания, но дают лучший контроль над архивированными файлами.
Дополнительные аргументы обозначены именем, которое является в сущности статическим целым значением. Значение аргумента может быть единственным или списком значений. В некоторых случаях они не имеют значения, а их название служит сигналом, чтобы выполнить какие-либо действия.
В следующем разделе мы опишем аргументы этих двух групп.

Дополнительные аргументы.


На сегодняшний день определены следующие аргументы:


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


<?php
$list = $archive->extract(PCLZIP_OPT_PATH, "extract/folder/");
?>

Этот аргумент может использоваться с методами 'extract();' и 'extractByIndex();'.


PCLZIP_OPT_ADD_PATH
Этот параметр позволяет указать путь для файла при добавлении его в архив. Это позволит заархивировать файл 'file.txt' с путем 'bacup/file.txt' или извлечь файл 'backup/file.txt' с путем 'folder/backup/file.txt'.
Значение – текстовая строка.


<?php
$list = $archive->create("file.txt,image.gif",
PCLZIP_OPT_ADD_PATH, "backup");
?>

Этот аргумент может использоваться с методами 'create();', 'add();', 'extract();'.


PCLZIP_OPT_REMOVE_PATH
Этот аргумент позволяет подавить часть или весь путь файлов (или папок) при их извлечении. Это позволит архивировать файл '/usr/local/user/test/file.txt' подобно файлу с названием 'test/file.txt' или извлекать файл, сохраненный как 'folder/data/file.txt' как файл 'data/file.txt'.
Значение – текстовая строка.


<?php
$list = $archive->add("/usr/local/user/test/file.txt",
PCLZIP_OPT_REMOVE_PATH, "/usr/local/user");
?>

Этот аргумент может использоваться совместно с методами 'create();', 'add();', 'extract();' и 'extractByIndex();'
Примечание: этот аргумент игнорируется, если вы используете аргумент PCLZIP_OPT_REMOVE_ALL_PATH в том же самом вызове метода.


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


<?php
$list = $archive->create("data/file.txt images/image.gif",
PCLZIP_OPT_REMOVE_ALL_PATH);
// Удалит путь 'data/' для файла 'data/file.txt'
// и путь 'images/' для файла 'images/image.gif'
?>

Может использоваться с методами 'create();', 'add();', 'extract();' и 'extractByIndex();'.


PCLZIP_OPT_SET_CHMOD
Дает возможность изменить атрибуты файла после его извлечения. На *NIX системах управление доступа и владелец файла (системный атрибут) не позволяют доступ к файлу отовсюду. В частности, пользователь, под которым запущен процесс PHP дает файлам только свои права, при определенных настройках они могут запрещать пользование файлами другими пользователями. Цель этого аргумента – назначить файлам нужные вам права.
Значение – одиночное октальное значение (например, 0777).


<?php
$list = $archive->extract(PCLZIP_OPT_SET_CHMOD, 0777);
?>

Этот аргумент может использоваться с методами 'extract();' и 'extractByIndex();'.
Примечание: этот аргумент не тестировался в полном объеме и носит статус ЭКСПЕРИМЕНТАЛЬНОГО.


PCLZIP_OPT_BY_NAME
Позволяет извлекать файлы из архива указывая их полное название.


<?php
$archive = new PclZip('test.zip');
$rule_list[0] = 'data/file1.txt';
$rule_list[1] = 'data/file2.txt';
$list = $archive->extract(PCLZIP_OPT_BY_NAME, $rule_list);
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

Фильтр может быть массивом или текстовой строкой с перечислением через запятую.


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_NAME, "data/file1.txt,data/file2.txt");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также: PCLZIP_OPT_BY_PREGPCLZIP_OPT_BY_INDEX и PCLZIP_OPT_BY_EREG.


PCLZIP_OPT_BY_EREG
Этот параметр позволяет извлекать файлы и папки отфильтровывая их регулярным выражением. Используется функция PHP 'ereg()'.


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_EREG, "txt$");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_BY_PREGPCLZIP_OPT_BY_NAME и PCLZIP_OPT_BY_INDEX.


PCLZIP_OPT_BY_PREG
Этот параметр позволяет извлекать файлы и папки отфильтровывая их регулярным выражением. Используется функция PHP 'preg()'.


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_PREG, "txt$");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_BY_EREGPCLZIP_OPT_BY_NAME и PCLZIP_OPT_BY_INDEX.


PCLZIP_OPT_BY_INDEX
Позволяет извлекать файлы и папки указывая их индексы в архиве.


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_INDEX, array ('0-4','2-7','10-33'));
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_BY_PREGPCLZIP_OPT_BY_NAME и PCLZIP_OPT_BY_EREG.


PCLZIP_OPT_EXTRACT_AS_STRING
Позволяет извлечь файл в строковую переменную а не в файл.
Это может понадобиться, если вы хотите получить содержимое файла без использования файловой системы.
Для примера:

 
  • показать '**readme*' файл;
  • непосредственно выдать файл пользователю (смотри так же PCLZIP_OPT_EXTRACT_IN_OUTPUT).

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


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_NAME, "data/readme.txt",
PCLZIP_OPT_EXTRACT_AS_STRING);
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
exit;
}
echo $list[0]['content'];
?>

См. также PCLZIP_OPT_EXTRACT_IN_OUTPUT.


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


<?php
$archive = new PclZip('test.zip');
$list = $archive->extract(PCLZIP_OPT_BY_NAME, "data/readme.txt",
PCLZIP_OPT_EXTRACT_IN_OUTPUT);
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_EXTRACT_AS_STRING.


PCLZIP_OPT_NO_COMPRESSION
Позволяет добавить файл в архив не сжимая его.


<?php
$archive = new PclZip('test.zip');
$list = $archive->add("data/file.txt", PCLZIP_OPT_NO_COMPRESSION);
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

PCLZIP_OPT_COMMENT
Позволяет добавить комментарий к архиву. Если комментарий уже существует, заменит его.


<?php
$archive = new PclZip('test.zip');
$list = $archive->create("data", PCLZIP_OPT_COMMENT, "Add a comment");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_ADD_COMMENT и PCLZIP_OPT_PREPEND_COMMENT.


PCLZIP_OPT_ADD_COMMENT
Позволяет добавить комментарий к архиву. Если комментарий уже существует, добавит новый комментарий в конец существующего.


<?php
$archive = new PclZip('test.zip');
$list = $archive->add("data", PCLZIP_OPT_ADD_COMMENT, "Add a comment after the existing one");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_COMMENT и PCLZIP_OPT_PREPEND_COMMENT.


PCLZIP_OPT_PREPEND_COMMENT
Позволяет добавить комментарий к архиву. Если комментарий уже существует, добавит новый комментарий перед имеющимся.


<?php
$archive = new PclZip('test.zip');
$list = $archive->add("data", PCLZIP_OPT_PREPEND_COMMENT, "Add a comment before the existing one");
if ($list == 0) {
echo "ERROR : ".$archive->errorInfo(true);
}
?>

См. также PCLZIP_OPT_COMMENT и PCLZIP_OPT_ADD_COMMENT.