По просьбам читателей, описываю работу с архивами на 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 'Не могу создать архив!';
}
Обратите внимание, добвлять файлы в архив можно двумя способами:
addFile — добавление существующего файла. Если не указывать 2-й параметр (имя файла в архиве), то, созданный внутри архива файл, будет иметь то же имя, что и исходный
addFromString — добавление в архив файла, с указанным нами содержимым ($zip->addFromString('info.txt', 'Этот архив создан средствами php!');)
addEmptyDir — добавление пустой папки в архив
Теперь научимся удалять файлы из архива
$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-систем.
Успехов в освоении!