Это архивная статья. Блог закрыт.

← на главную

ZipArchive — работа с архивами на php

Статья написана очень давно — 13.08.2010

По просьбам читателей, описываю работу с архивами на php

Начиная с PHP 5.2 «в комплекте» есть замечательная библиотека под названием ZipArchive. Вот её-то мы и рассмотрим.
Если у вас версия php меньше, чем 5.2, если у вас появляется ошибка class ziparchive not found, то советую данную библиотеку скачать и установить.

Работа с библиотекой ZipArchive довольно проста. Для начала нужно объявить экземпляр её класса:

$zip = new ZipArchive;

После этого, мы сможем работать с объектом $zip (работа с ним заключается в вызове того или другого метода). Обычно, самый первый метод — это открытие архива (как для создания, так и для чтения)

//чтение:
$zip->open('путь к архиву');
//создание:
$zip->open('путь к создаваемому архиву', ZipArchive::CREATE);

Не забывайте делать проверки ошибок, это важно. Ведь, например, запрашиваемого файла архива может не существовать, что тогда?

Распаковка архива средствами php (а точней, средствами ZipArchive) происходит с помощью метода extractTo

//Распаковка архива на сервере
$zip = new ZipArchive;
if ($zip->open('your_archive.zip') === true){
	$zip->extractTo('папка для разархивирования');
	//а это - закрытие архива по окончании работы с ним. Хороший тон программирования.
	$zip->close();
}else{
	echo 'Не могу найти файл архива!';
}

Создание архива средствами php можно осуществить так:

//Создание архива на сервере
$zip = new ZipArchive;
if ($zip->open('created_by_php.zip', ZipArchive::CREATE) === true){
	$zip->addFile('имя файла на сервере', 'имя файла в архиве');
	$zip->addFromString('имя файла в архиве', 'данные файла');
	$zip->addEmptyDir('имя папки');
	$zip->close();
}else{
	echo 'Не могу создать архив!';
}

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

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

$zip = new ZipArchive;
if ($zip->open('archive.zip') === true){
	//удаление файла
	$zip->deleteName('info.txt');
	//удаление директории (точно так же):
	$zip->deleteName('tempdir/');
	$zip->close();
}else{
	echo 'Не могу найти файл архива!';
}

Самый первый пример — распаковка архива на сервер. Распаковывать-то мы научились, а теперь научимся извлекать определённый файл из архива

$zip = new ZipArchive;
if ($zip->open('archive.zip') === true){
	//получаем файл info.txt и выводим его на экран:
	echo $zip->getFromName('info.txt');
	$zip->close();
}else{
	echo 'Не могу найти файл архива!';
}

И ещё один полезный пример — переименовывание файла в архиве

$zip = new ZipArchive;
if ($zip->open('archive.zip') === true){
	$zip->renameName('текущее_имя_файла.txt','новое_имя_файла.txt');
	$zip->close();
}else{
	echo 'Не могу найти файл архива!';
}

Архиватор на php

А теперь, вооружившись полученными знаниями, напишем небольшой простейший архиватор на php, работающий на рассмотренной ZipArchive. Разработку интерфейса оставляю за вами, здесь рассмотрим только программную часть

Цель: разработать архиватор на php, умеющий распаковывать и запаковывать архивы
Пусть на сервере будет папка unpacked, в которую мы будем помещать незапакованные файлы, а также туда будут распаковываться архивы
Решение:

$zip = new ZipArchive;
if ((isset($_GET['act']))&&($_GET['act']=='unzip')){
	if (isset($_GET['filename'])){
		if ($zip->open($_GET['filename']) === true){
			$zip->extractTo('unpacked/');
			$zip->close();
		}else{
			echo 'Ошибка! Архив с таким именем не задан!';
		}
	}else{
		echo 'Ошибка! Не задано имя архива!';
	}
}elseif((isset($_GET['act']))&&($_GET['act']=='zip')){
	if ($zip->open('unpacked/archive.zip', ZipArchive::CREATE) === true){
		$allfiles   =   array();
                recoursiveDir('unpacked');
		foreach ($allfiles as $key=>$val){
			$zip->addFile($val);
		}
		$zip->close();
                //указываем в заголовках тип передаваемых данных: архив zip
                header('Content-type: application/zip; name=ziparchive.zip');
                //отдаём файл архива
                echo file_get_contents('unpacked/archive.zip');
	}else{
		echo 'Ошибка! Невозможно создать архив!';
	}
}else{
	echo '
            <form method="GET" action="?">
                <input type="radio" name="act" value="unzip" /> Распаковать
<input type="radio" name="act" value="zip" /> Запаковать
Введите имя архива (для распаковки предварительно загрузив его на сервер): <br /><input type="text" name="filename" value="" /> <br /><input type="submit" value="Выполнить" /> </form> '; } //эта функция рекурсивно обходит все папки и составляет список файлов //результат её работы можете посмотреть, вывев var_dump($allfiles) после её вызова function recoursiveDir($dir){ global $allfiles; if ($files = glob($dir.'/*')){ foreach($files as $file){ if (is_dir($file)){ recoursiveDir($file); }else{ $allfiles[] = $file; } } } }

Получение списка файлов в архиве

Как справедливо заметил 2medic в комментариях, упустил я один важный момент — как получить список всех файлов в архиве? Что-ж, восполню этот пробел

У класса ZipArchive есть такое замечательное свойство, как numFiles — количество файлов в архиве. Его, а также метод getNameIndex (получение имени по индексу) мы и будем использовать. Не буду углубляться в теорию, просто покажу пример:

$zip           = new ZipArchive;
//сюда будем складывать имена файлов...
$filenames = array();

if ($zip->open('archive.zip') === true){
     //цикл, проходим по индексам (читай - порядковым номерам) файлов
     for($i=0; $i<$zip->numFiles; $i++){
          //с помощью метода getNameIndex получаем имя элемента по индексу 
          //и помещаем в наш массив имён ;) 
          $filenames[] = $zip->getNameIndex($i);
     }
}else{
     echo 'А архивчик-то, битый!';
}

Ничего сложного, ведь правда?

Домашнее задание: к распаковке сделайте предварительную загрузку архивов (чтобы не по ftp каждый раз загружать архив, а через web).
Также, можно усовершенстовать этот скрипт до полноценного php-архиватора, и пользоваться им наздоровье!

В заключении пару слов. Не забывайте о правах доступа! Если по неведомой вами причине, архив не создаётся, либо архив не распаковывается в указанную папку, проверьте права доступа к этим папкам! В самом простом случае создайте папку и задайте ей права 777. Понятное дело, это касаемо только unix-систем.
Успехов в освоении!

Комментарии удалены

© koz1024 2010, 2025