Создание zip архивов с помощью PHP скрипта

Владимир | | PHP.

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

Прежде всего, убедитесь, что включена поддержка всех нужных функций. Для этого в файле php.ini нужно убрать символ комментария (;) в начале строки:
extension=php_zip.dll

Теперь переходим к созданию архива.
Все операции с архивом выполняются с помощью объекта ZipArchive, создать его не сложно:

$zip = new ZipArchive();

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

Если на этом этапе ошибок не произошло, то с помощью метода addFile() можно добавить в архив файлы. Метод принимает два параметра:
первый – имя исходного файла;
второй – имя под которым файл будет добавлен в архив (если этот параметр не указан, будет использовано имя из первого параметра).

Примечание. Тут есть один нюанс. Если имя исходного файла “d:/docs/myfile.txt” и вы не укажите второй параметр, то в архиве будет создана папка “d”, а в ней – “docs”. Файл “myfile.txt” будет размещен в “docs”. Чтобы избежать создания папок в архиве просто укажите во втором параметре “myfile.txt”, и тогда файл будет размещен в корне архива.

Завершает работу с архивом метод close().

Так, с теорией закончили. Теперь посмотрим, как все это работает на примере.

Напишем небольшой скрипт, который будет создавать архив со всеми файлами из какой-нибудь папки.

<?php
//папка в которой будет размещен архив
$archive_dir = "E:/archiveFolder/";
//папка с исходными файлами
$src_dir = "E:/srcFolder/";

//создание zip архива
$zip = new ZipArchive();
//имя файла архива
$fileName = $archive_dir."backup_".date('j_m_Y_h_i_s').".zip";
if ($zip->open($fileName, ZIPARCHIVE::CREATE) !== true) {
	fwrite(STDERR, "Error while creating archive file");
	exit(1);
}

//добавляем файлы в архив все файлы из папки src_dir
$dirHandle = opendir($src_dir);
while (false !== ($file = readdir($dirHandle))) {
	$zip->addFile($src_dir.$file, $file);
}
//закрываем архив
$zip->close();

fwrite(STDOUT, "Archive created\n");

exit(0);
?>

Переменная $src_dir содержит путь к папке с исходными файлами, а $archive_dir – путь к папке в которой будет создан архив.

Примечание: учтите, что наш скрипт эти папки не создает, поэтому сделайте это самостоятельно.

В переменной $fileName содержится имя архива. К имени я добавил дату и время создания архива в формате “день_месяц_год_часы_минуты_секунды”. Это позволяет многократно запускать скрипт и не думать о том, что новая версия архива запишется поверх старой.

В строках 11-14 мы открываем архив, при этом используется константа ZIPARCHIVE::CREATE, которая указывает, что если архива не существует, то он должен быть создан. Если во время создание архива возникли ошибки, выводим сообщение и завершаем работу.

После этого, мы открываем папку с исходными файлами и добавляем их в архив (строки 17-20).
Метод close() (в строке 22) закрывает архив.

Запускаем скрипт:
php путь_к_скрипту\имя_скрипта.php

Если ошибок не было, в папке «E:/archiveFolder/» вы будет создан архив.

Как видите, ничего сложного. В следующий раз я покажу как извлечь файлы из архива.

Постовой

Если нужен щебень заходите на vost.ru

  • Виктор

    А можно ли задать уровень компрессии (минимальный, максимальный…)?

  • Виктор

    А можно ли задать уровень компрессии (минимальный, максимальный…)?

  • Честно говоря, я не нашел в документации четкого ответа.
    Но для создания архива PHP использует библиотеку zlib, для которой в php.ini можно задать два параметра:
    zlib.output_compression
    zlib.output_compression_level

    Если есть желание, попробуйте поиграться.

  • Честно говоря, я не нашел в документации четкого ответа.
    Но для создания архива PHP использует библиотеку zlib, для которой в php.ini можно задать два параметра:
    zlib.output_compression
    zlib.output_compression_level

    Если есть желание, попробуйте поиграться.

  • Юлия

    А обязательно прописывать путь, по которому будет создан архив? Можно ли сделать так, чтобы пользователь сам выбрал, куда он хочет сохранить свой файл архива?

    • Можно, только это зависит от интерфейса с которым работает пользователь.

      Если используется web интерфейс, то, один из вариантов, создать форму в которую он будет вводить путь к архиву. А после этого подставлять введенный путь.

  • Юлия

    А обязательно прописывать путь, по которому будет создан архив? Можно ли сделать так, чтобы пользователь сам выбрал, куда он хочет сохранить свой файл архива?

    • Можно, только это зависит от интерфейса с которым работает пользователь.

      Если используется web интерфейс, то, один из вариантов, создать форму в которую он будет вводить путь к архиву. А после этого подставлять введенный путь.

  • Вячеслав

    а можно ли зазиповать целую папку с файлами?

    • Одной строкой кода — нет.
      Но в этой статье я привел скрипт создания архива целой папки (последний листинг). Он в цикле проходит по всей папке и добавляет в архив все найденные файлы.
      В общем-то его не сложно изменить для просмотра вложенных папок.

    • exolon

      Сниппет для архивирования папки в zip-архив с помощью php. Надеюсь пригодится.
      open('my-archive.zip', ZIPARCHIVE::CREATE) !== TRUE) {
      die ("Could not open archive");
      }

      // initialize an iterator
      // pass it the directory to be processed
      $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("app/"));

      // iterate over the directory
      // add each file found to the archive
      foreach ($iterator as $key=>$value) {
      $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
      }

      // close and save archive
      $zip->close();
      echo "Archive created successfully.";
      ?>

      Взято отсюда.

  • Вячеслав

    а можно ли зазиповать целую папку с файлами?

    • Одной строкой кода — нет.
      Но в этой статье я привел скрипт создания архива целой папки (последний листинг). Он в цикле проходит по всей папке и добавляет в архив все найденные файлы.
      В общем-то его не сложно изменить для просмотра вложенных папок.

    • exolon

      Сниппет для архивирования папки в zip-архив с помощью php. Надеюсь пригодится.
      open('my-archive.zip', ZIPARCHIVE::CREATE) !== TRUE) {
      die ("Could not open archive");
      }

      // initialize an iterator
      // pass it the directory to be processed
      $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("app/"));

      // iterate over the directory
      // add each file found to the archive
      foreach ($iterator as $key=>$value) {
      $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
      }

      // close and save archive
      $zip->close();
      echo "Archive created successfully.";
      ?>

      Взято отсюда.

  • Иоган

    🙁 у меня не работает, пишет
    «Fatal error: Cannot instantiate non-existent class: ziparchive in y:homelocalhostwwwfotoindex.php on line 10»
    хотя и в файле пхп.ини убрал значок комента….
    в чем дело??может потомучто у меня стоит Денвер?

  • Иоган

    🙁 у меня не работает, пишет
    «Fatal error: Cannot instantiate non-existent class: ziparchive in y:\home\localhost\www\foto\index.php on line 10»
    хотя и в файле пхп.ини убрал значок комента….
    в чем дело??может потомучто у меня стоит Денвер?

  • Иоган

    я уже даже скачал php_zip.dll и закинул в папку extensions…ошибка всё таже… почему не работает….??

  • Иоган

    я уже даже скачал php_zip.dll и закинул в папку extensions…ошибка всё таже… почему не работает….??

  • Посмотрите, что выводит phpinfo(). Там должен быть раздел zip. И в нем параметры
    Zip: enabled

    Extension Version: $Id: php_zip.c,v 1.1.2.38 2007/08/06 22:02:32 bjori Exp $

    Zip version: 2.0.0

    Libzip version: 0.7.1

    Версии могут отличаться.

  • Посмотрите, что выводит phpinfo(). Там должен быть раздел zip. И в нем параметры
    Zip: enabled

    Extension Version: $Id: php_zip.c,v 1.1.2.38 2007/08/06 22:02:32 bjori Exp $

    Zip version: 2.0.0

    Libzip version: 0.7.1

    Версии могут отличаться.

  • Иоган

    там написано:
    Zip support: enabled

    и всё! как его подключать?

    • Подключать никак не надо. После того как библиотека загружена, $zip = new ZipArchive(); должен создать объект.

      Вообще ситуация странная. Если хотите, отправьте мне скрипт по email, попробую запустить у себя.

  • Иоган

    там написано:
    Zip support: enabled

    и всё! как его подключать?

    • Подключать никак не надо. После того как библиотека загружена, $zip = new ZipArchive(); должен создать объект.

      Вообще ситуация странная. Если хотите, отправьте мне скрипт по email, попробую запустить у себя.

  • пользуйтесь онлайн сервисом OnlineZIP.cn для создания архивов и отправки его на любой мейл

  • пользуйтесь онлайн сервисом OnlineZIP.cn для создания архивов и отправки его на любой мейл

  • Pingback: Блог web-мастера » Работа с архивами средствами PHP()

  • koza4ok

    Внедрил скрипт, всё вроде хорошо работает, но если размер архива достигает 128кб, возвращаетса битый архив… счем может быть связана проблемма?

    • Возможная причина — ограничение времени выполнения скрипта или максимального объема памяти.
      Настройки в php.ini:
      memory_limit
      max_execution_time

  • koza4ok

    Внедрил скрипт, всё вроде хорошо работает, но если размер архива достигает 128кб, возвращаетса битый архив… счем может быть связана проблемма?

    • Возможная причина — ограничение времени выполнения скрипта или максимального объема памяти.
      Настройки в php.ini:
      memory_limit
      max_execution_time

  • exolon

    Спасибо, помогло 🙂

  • exolon

    Спасибо, помогло 🙂

  • anton

    у меня тоже не создает объект 🙁 🙁

    Class 'ZipArchive' not found in Z:homelocalhostwwwMytestmusic.sevstar.netZIPzip.php on line 8

    хотя в php.ini раскоментил extension=php_zip.dll

    В php.info ZIPа нету … 🙁

    • В php.info ZIPа нету …

      А сервер перезапускали?

  • anton

    у меня тоже не создает объект 🙁 🙁

    Class 'ZipArchive' not found in Z:\home\localhost\www\Mytest\music.sevstar.net\ZIP\zip.php on line 8

    хотя в php.ini раскоментил extension=php_zip.dll

    В php.info ZIPа нету … 🙁

    • В php.info ZIPа нету …

      А сервер перезапускали?

  • anton

    естественно :))

    сейчас разместил не у себя, а на сервере другом. Эта проблешма ушла, но появилась следующая:
    в строке fwrite(STDOUT, «Archive createdn»)

    пишет:

    Warning: fwrite(): supplied argument is not a valid stream resource in …

    хотя в коде у мну вот так:

    $archive_dir = «archiveFolder/»;

    $src_dir = «1/»;

    в папке «1» пара фалов а «archiveFolder» не существует. ПРОбовл ставить и существующую, но та же проблема…

    • Попробуйте проверить существуют ли папки
      is_dir($archive_dir)
      is_dir($src_dir)

      если эти функции вернуть false, то папок не существует.

      В этом случае попробуйте указать полный путь к папке.

    • Небольшая поправка.
      Проверять нужно только $src_dir раз archiveFolder не существует.

  • anton

    естественно :))

    сейчас разместил не у себя, а на сервере другом. Эта проблешма ушла, но появилась следующая:
    в строке fwrite(STDOUT, «Archive created\n»)

    пишет:

    Warning: fwrite(): supplied argument is not a valid stream resource in …

    хотя в коде у мну вот так:

    $archive_dir = «archiveFolder/»;

    $src_dir = «1/»;

    в папке «1» пара фалов а «archiveFolder» не существует. ПРОбовл ставить и существующую, но та же проблема…

    • Попробуйте проверить существуют ли папки
      is_dir($archive_dir)
      is_dir($src_dir)

      если эти функции вернуть false, то папок не существует.

      В этом случае попробуйте указать полный путь к папке.

    • Небольшая поправка.
      Проверять нужно только $src_dir раз archiveFolder не существует.

  • Ex

    А как происходит обратный процесс, когда требуется разархивировать файлы?

    • Используйте метод ZipArchive::extractTo (для разархивирования)
      Например,
      $zip = new ZipArchive;
      if ($zip->open('test.zip') === TRUE) {
      $zip->extractTo('/my/destination/dir/');
      $zip->close();
      echo 'ok';
      } else {
      echo 'failed';
      }

      Подробная документация здесь.

  • Ex

    А как происходит обратный процесс, когда требуется разархивировать файлы?

    • Используйте метод ZipArchive::extractTo (для разархивирования)
      Например,
      $zip = new ZipArchive;
      if ($zip->open('test.zip') === TRUE) {
      $zip->extractTo('/my/destination/dir/');
      $zip->close();
      echo 'ok';
      } else {
      echo 'failed';
      }

      Подробная документация здесь.

  • Ex

    Благодарю 😉

  • Ex

    Благодарю 😉

  • Есть немного другой алгоритм :

  • Есть немного другой алгоритм :

  • Сори предыдущий можно удалить комент, не разобрался с тэгами 🙂
    Есть другой алгоритм Создание Zip на php

    • Интересно, а производительность вы не сравнивали?

  • Сори предыдущий можно удалить комент, не разобрался с тэгами 🙂
    Есть другой алгоритм Создание Zip на php

    • Интересно, а производительность вы не сравнивали?

  • Lev

    С файлами понятно, а если надо упаковать не файлы, а данные которые уже находятся в памяти?
    Например данные могут динамически генерироваться или содержаться в скрипте в виде строк.

  • Lev

    С файлами понятно, а если надо упаковать не файлы, а данные которые уже находятся в памяти?
    Например данные могут динамически генерироваться или содержаться в скрипте в виде строк.

  • Lev

    С файлами как понятно. А если надо упаковать не файлы а данные которые уже находятся в памяти? Например данные динамически генерируются на лету или находятся в скрипте в виде строк.

    • В zip архиве в любом случае должны быть файлы. Но вы можете использовать метод addFromString для того чтобы добавить в архив данные из памяти (при этом нужно будет указать имя файла который будет создан в архиве с этими данными).

  • Lev

    С файлами как понятно. А если надо упаковать не файлы а данные которые уже находятся в памяти? Например данные динамически генерируются на лету или находятся в скрипте в виде строк.

    • В zip архиве в любом случае должны быть файлы. Но вы можете использовать метод addFromString для того чтобы добавить в архив данные из памяти (при этом нужно будет указать имя файла который будет создан в архиве с этими данными).

  • юра диденко

    Как сделать чтобы архив создавался в текущей папке? в котором были бы все файлы сайта. (я незнаю полный путь к этим файлам) Спасибо!

    • Если вы не знаете размещение файлов, то заархивировать их вы не сможете.
      Если эти файлы находятся в той же папке, что и ваш скрипт, то узнать путь к нему можно с помощью $_SERVER['SCRIPT_FILENAME']

  • юра диденко

    Как сделать чтобы архив создавался в текущей папке? в котором были бы все файлы сайта. (я незнаю полный путь к этим файлам) Спасибо!

    • Если вы не знаете размещение файлов, то заархивировать их вы не сможете.
      Если эти файлы находятся в той же папке, что и ваш скрипт, то узнать путь к нему можно с помощью $_SERVER['SCRIPT_FILENAME']

  • Сергей

    Здравствуйте!
    Скопировал скрипт, вместо диска «е» указал «z», так как использую денвер. Пишет ошибку Warning: fwrite(): supplied argument is not a valid stream resource in Z:homearch.ruwww1.php on line 24
    zipZip enabled
    Extension Version $Id: php_zip.c,v 1.1.2.49 2009/02/05 19:53:22 pajoye Exp $
    Zip version 1.8.11
    Libzip version 0.9.0
    А при проверке на наличие директории (is_dir($src_dir)) пишеь 1.
    Заранее спасибо.

    • Попробуйте изменить адрес на
      Z:/home/arch.ru/www/1.php

  • Сергей

    Здравствуйте!
    Скопировал скрипт, вместо диска «е» указал «z», так как использую денвер. Пишет ошибку Warning: fwrite(): supplied argument is not a valid stream resource in Z:\home\arch.ru\www\1.php on line 24
    zipZip enabled
    Extension Version $Id: php_zip.c,v 1.1.2.49 2009/02/05 19:53:22 pajoye Exp $
    Zip version 1.8.11
    Libzip version 0.9.0
    А при проверке на наличие директории (is_dir($src_dir)) пишеь 1.
    Заранее спасибо.

    • Попробуйте изменить адрес на
      Z:/home/arch.ru/www/1.php

  • Алексей

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

    • То, что хостинг бесплатный — это хорошо… но их много и они разные 😉
      У вас есть какая-нибудь панель управления или движок какой-то установлен?
      Если вы можете выполнять свои php скрипты, то сделать однозначно можно. Если не можете, то все зависит от возможностей панели управления.

  • Алексей

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

    • То, что хостинг бесплатный — это хорошо… но их много и они разные 😉
      У вас есть какая-нибудь панель управления или движок какой-то установлен?
      Если вы можете выполнять свои php скрипты, то сделать однозначно можно. Если не можете, то все зависит от возможностей панели управления.

  • lio

    А можно ли усложнить пример?

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

    пример реализовать возможно? зарание спс.

    • Да, усложнить можно, но что означает передать клиенту? Отправить почтой?
      Или клиент заходит на сайт и выбирает файл из какого-нибудь списка?

  • lio

    А можно ли усложнить пример?

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

    пример реализовать возможно? зарание спс.

    • Да, усложнить можно, но что означает передать клиенту? Отправить почтой?
      Или клиент заходит на сайт и выбирает файл из какого-нибудь списка?

  • Николай

    А как можно создать запороленный архив при помощи php, можно ли его вообще создать при помощи php?

    • Это можно сделать с помощью с помощью внешних утилит, например, 7-zip. Этот архиватор допускает работу в режиме командной строки, т.е. его можно запустить с помощью функции exec

      exec(«"c:\program files\7-zip\7z.exe" a archive.7z -psecret -mhe *.txt»);

      где secret — пароль
      Путь к архиватору, естественно, нужно указать ваш.
      Параметры командной строки описаны в справке.
      " — это дополнительные кавычки, нужны, т.к. program files содержит пробел

      • Роман

        Добрый день! Подскажите пожалуйста, а как распаковать запароленный r2z архив!

        • Никогда не работал с этим форматом.

        • Роман

          Ну ладно! А как через PHP распаковать запароленый zip архив?

        • Библиотека ZipArchive запароленные архивы не поддерживает. Есть возможность вызова произвольной команды из php. С помощью функции exec, т.е. если вы можете из консоли распаковать архив, то сможете и из php скрипта. Пример использования тремя комментариями выше.

      • Роман

        Добрый день! Подскажите пожалуйста, а как распаковать запароленный r2z архив!

    • Dmitriatika

      Создать и запаролить:

      Распаковать$cmd = «`which unzip` -P {$password} {$zipFile} -d {$destDir}»;exec($cmd);

      • Роман

        А можно поподробней узнать про распаковку!
        что такое $zipFile? Если это путь к zip-у, то проблема такая, я написал так что у меня во время upload-а zip распаковывается! То какой тогда путь будет, или это необязательный параметр?

        • Роман

          Точней не $zipFile, а $destDir?

        • VINTproYKT

          Destiny directory это. То есть, это директория, в которую нужно распаковать содержимое архива.

        • destDir — сокращение от destination directory (destiny — судьба).

      • Роман

        Дмитрий, помогите пожалуйста! Не знаю как сделать одну вещь, я ещё пока что новичок в работе с этим классом! Не могу разобраться ломаю голову уже 7 месяцев! Код есть нужно только добавить строку для распароливания не могу понять куда! Не получается!

  • Николай

    А как можно создать запороленный архив при помощи php, можно ли его вообще создать при помощи php?

    • Это можно сделать с помощью с помощью внешних утилит, например, 7-zip. Этот архиватор допускает работу в режиме командной строки, т.е. его можно запустить с помощью функции exec

      exec(«"c:\\program files\\7-zip\\7z.exe" a archive.7z -psecret -mhe *.txt»);

      где secret — пароль
      Путь к архиватору, естественно, нужно указать ваш.
      Параметры командной строки описаны в справке.
      " — это дополнительные кавычки, нужны, т.к. program files содержит пробел

  • Class 'ZipArchive' not found in
    Ошибка даже после перезапуска Денвера. Что можно сделать?

    • Проверить подключена ли библиотека.
      В php.ini должна быть раскоментированна строка
      extension=php_zip.dll

  • Class 'ZipArchive' not found in
    Ошибка даже после перезапуска Денвера. Что можно сделать?

    • Проверить подключена ли библиотека.
      В php.ini должна быть раскоментированна строка
      extension=php_zip.dll

  • lio

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

    • Решение «в лоб».
      Написать отдельный скрипт, который будет чистить папку tmp и запускать этот скрипт cron'ом.

  • lio

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

    • Решение «в лоб».
      Написать отдельный скрипт, который будет чистить папку tmp и запускать этот скрипт cron'ом.

  • А готовый файл менеджер с поддержкой zip на php никто не подскажет? Желательно небольшой.
    Заранее благодарен.

  • А готовый файл менеджер с поддержкой zip на php никто не подскажет? Желательно небольшой.
    Заранее благодарен.

  • lio

    вообщем зделал. но всеравно зип в начале нужно сохранить а потом только удалить! 🙂 может еще что подскажите горе програмисту(зачем учится языку програмирования, когда можно посматреть как это делают другие!).
    $value ) {
    $$key=$value;
    }
    } else {
    foreach ( $HTTP_GET_VARS as $key => $value ) {
    $$key=$value;
    }
    }

    if (!$lang) {
    if (substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) == 'ru') {
    $lang=ru;
    } else {
    $lang=en;
    }
    }

    require("config.php");
    require("lang/".$lang.".php");

    // Устанавливаем соединение с FTP-сервером
    if ($ftp_server) {
    if ($ftp_port) {
    if(!$connect = @ftp_connect($ftp_server, $ftp_port)) {
    error_mes(LANG_NO_CON);
    } else {
    if (!$loginOn = @ftp_login($connect, $ftp_user, $ftp_password)) error_mes(LANG_NO_REG);
    }
    } else {
    error_mes(LANG_PORT);
    }
    } else {
    error_mes(LANG_SERVER);
    }

    // Запрос файла на передачу
    if ($get) {
    @ftp_chdir($connect, $dir) or error_mes(LANG_ERROR_LOST);
    file_get($connect, $get, $tempdir, $dir);
    }
    // Если нет запроса, то продолжаем вывод списка

    $list = @ftp_rawlist($connect, $dir) or error_mes(LANG_ERROR_LOST);

    print "";
    print "".LANG_NAME."".LANG_SIZE."".LANG_DATA."".LANG_TIME."n";

    list_ftp($list);
    @ftp_close($connect) or error_mes(LANG_ERROR_LOST);

    print " ";
    $time = date("U");
    print "$time";

    function list_ftp($list)
    {

    // Получаем все файлы выбранного каталога, указаного в config.php
    // Выводим содержимое каталога
    foreach($list as $file)
    {
    // Разбиваем строку по пробельным символам
    // Примечание: файлы не могут содержать пробелы в имени
    list($acc,
    $bloks,
    $group,
    $user,
    $size,
    $month,
    $day,
    $time,
    $file) = preg_split("/[s]+/", $file);
    if(substr($acc, 0, 1) == '-')
    {
    print "";
    print "". $file . "";
    print "".file_size($size)."";
    print "". $month . "," . $day . "";
    print "" . $time . "";
    print "n";
    }
    }
    }

    // Приобразовываем в нормальный размер
    function file_size($size) {
    $gb = 1024*1024*1024;
    $mb = 1024*1024;
    if ($size >= $gb) {$size = sprintf ("%01.2f",$size/$gb) . " GB";}
    else if ( $size >= $mb ) {$size = sprintf ("%01.2f",$size/$mb) . " MB";}
    else if ( $size >= 1024 ) {$size = sprintf ("%01.2f",$size/1024) . " KB";}
    else {$size = $size . " byte";}
    return $size;
    }

    // Вывод ошибок
    function error_mes($mes) {
    print "Time: ". date("U") ."Message: $mes";
    exit;
    }

    function file_get($connect,$get,$tempdir,$dir) {

    $fp = fopen($tempdir . $get, "w");
    @ftp_fget($connect, $fp, $get, FTP_BINARY) or error_mes(LANG_ERROR_DOWN);
    fclose($fp);
    @ftp_close($connect) or error_mes(LANG_ERROR_LOST);
    $zip = new ZipArchive;
    $zipfile = $get.".zip";
    $res = $zip -> open($tempdir . $zipfile, ZIPARCHIVE::CREATE);
    $zip -> addFromString("string.txt", "Это строка, которая будет записана в файл string.txt, а сам файл помещен в архив");
    // Файл file.txt будет помещен в архив под именем file_zip.txt
    $zip -> addFile($tempdir . $get, "$get");
    $zip -> close();
    header("Content-disposition: attachment; filename="$zipfile"");
    header("Content-type: application/octetstream");
    readfile($tempdir . $zipfile);
    unlink($tempdir . $get);
    unlink($tempdir . $zipfile);
    exit;
    }
    ?>

    так в месте с отладкой и доработкой!

    • зачем учится языку програмирования, когда можно посматреть как это делают другие

      Например, чтобы понять куда вставлять чужой код 🙂

  • lio

    вообщем зделал. но всеравно зип в начале нужно сохранить а потом только удалить! 🙂 может еще что подскажите горе програмисту(зачем учится языку програмирования, когда можно посматреть как это делают другие!).
    $value ) {
    $$key=$value;
    }
    } else {
    foreach ( $HTTP_GET_VARS as $key => $value ) {
    $$key=$value;
    }
    }

    if (!$lang) {
    if (substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) == 'ru') {
    $lang=ru;
    } else {
    $lang=en;
    }
    }

    require("config.php");
    require("lang/".$lang.".php");

    // Устанавливаем соединение с FTP-сервером
    if ($ftp_server) {
    if ($ftp_port) {
    if(!$connect = @ftp_connect($ftp_server, $ftp_port)) {
    error_mes(LANG_NO_CON);
    } else {
    if (!$loginOn = @ftp_login($connect, $ftp_user, $ftp_password)) error_mes(LANG_NO_REG);
    }
    } else {
    error_mes(LANG_PORT);
    }
    } else {
    error_mes(LANG_SERVER);
    }

    // Запрос файла на передачу
    if ($get) {
    @ftp_chdir($connect, $dir) or error_mes(LANG_ERROR_LOST);
    file_get($connect, $get, $tempdir, $dir);
    }
    // Если нет запроса, то продолжаем вывод списка

    $list = @ftp_rawlist($connect, $dir) or error_mes(LANG_ERROR_LOST);

    print "";
    print "".LANG_NAME."".LANG_SIZE."".LANG_DATA."".LANG_TIME."\n";

    list_ftp($list);
    @ftp_close($connect) or error_mes(LANG_ERROR_LOST);

    print " ";
    $time = date("U");
    print "$time";

    function list_ftp($list)
    {

    // Получаем все файлы выбранного каталога, указаного в config.php
    // Выводим содержимое каталога
    foreach($list as $file)
    {
    // Разбиваем строку по пробельным символам
    // Примечание: файлы не могут содержать пробелы в имени
    list($acc,
    $bloks,
    $group,
    $user,
    $size,
    $month,
    $day,
    $time,
    $file) = preg_split("/[\s]+/", $file);
    if(substr($acc, 0, 1) == '-')
    {
    print "";
    print "". $file . "";
    print "".file_size($size)."";
    print "". $month . "," . $day . "";
    print "" . $time . "";
    print "\n";
    }
    }
    }

    // Приобразовываем в нормальный размер
    function file_size($size) {
    $gb = 1024*1024*1024;
    $mb = 1024*1024;
    if ($size >= $gb) {$size = sprintf ("%01.2f",$size/$gb) . " GB";}
    else if ( $size >= $mb ) {$size = sprintf ("%01.2f",$size/$mb) . " MB";}
    else if ( $size >= 1024 ) {$size = sprintf ("%01.2f",$size/1024) . " KB";}
    else {$size = $size . " byte";}
    return $size;
    }

    // Вывод ошибок
    function error_mes($mes) {
    print "Time: ". date("U") ."Message: $mes";
    exit;
    }

    function file_get($connect,$get,$tempdir,$dir) {

    $fp = fopen($tempdir . $get, "w");
    @ftp_fget($connect, $fp, $get, FTP_BINARY) or error_mes(LANG_ERROR_DOWN);
    fclose($fp);
    @ftp_close($connect) or error_mes(LANG_ERROR_LOST);
    $zip = new ZipArchive;
    $zipfile = $get.".zip";
    $res = $zip -> open($tempdir . $zipfile, ZIPARCHIVE::CREATE);
    $zip -> addFromString("string.txt", "Это строка, которая будет записана в файл string.txt, а сам файл помещен в архив");
    // Файл file.txt будет помещен в архив под именем file_zip.txt
    $zip -> addFile($tempdir . $get, "$get");
    $zip -> close();
    header("Content-disposition: attachment; filename=\"$zipfile\"");
    header("Content-type: application/octetstream");
    readfile($tempdir . $zipfile);
    unlink($tempdir . $get);
    unlink($tempdir . $zipfile);
    exit;
    }
    ?>

    так в месте с отладкой и доработкой!

    • зачем учится языку програмирования, когда можно посматреть как это делают другие

      Например, чтобы понять куда вставлять чужой код 🙂

  • Владимир

    Такой вопрос, создаю скриптом архив, количество файлов 7000, после добавления 500 архив закрыть не может, ставлю ограничение на 500 файлов все нормально. memory_limit ставил разные значения исход тот же.

    • Есть еще параметр из-за которого может возникнуть такая проблема
      max_execution_time

      • Владимир

        Извините про лимит забыл сказать, я поставил в скрипте 3600, с большим запасом, соответственно проблема та же.

        • Вы работаете с выделенным сервером? Если да, то есть вариант обойти эту проблему. С помощью 7-zip или другого внешнего архиватора. Т.е. запустить его с помощью exec.

    • Алексей

      Можно добавлять к существующему архиву, т.е. порциями по 100-500 файлов, например

  • Владимир

    Такой вопрос, создаю скриптом архив, количество файлов 7000, после добавления 500 архив закрыть не может, ставлю ограничение на 500 файлов все нормально. memory_limit ставил разные значения исход тот же.

    • Есть еще параметр из-за которого может возникнуть такая проблема
      max_execution_time

      • Владимир

        Извините про лимит забыл сказать, я поставил в скрипте 3600, с большим запасом, соответственно проблема та же.

        • Вы работаете с выделенным сервером? Если да, то есть вариант обойти эту проблему. С помощью 7-zip или другого внешнего архиватора. Т.е. запустить его с помощью exec.

  • lio

    по дефолту работа скрипта 30 секунд, если лимит времени привышен, то скрипт ведет себя не коректно! надо прописать лимит на скрипт больше, если того требует время работы скрипта.

  • lio

    по дефолту работа скрипта 30 секунд, если лимит времени привышен, то скрипт ведет себя не коректно! надо прописать лимит на скрипт больше, если того требует время работы скрипта.

  • Владимир

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

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

  • Владимир

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

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

  • Dockeee

    Попробовал немного видоизменить код — свести его в функцию, и архивировать отдельный файл, но ничего не выходит
    Сама функция (файл func.php):

    function ZIPFile($src_file, $tgt_file){
    $zip = new ZipArchive();
    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE!==true)) {
    print("Ошибка создания архива");
    exit(1);
    }
    $zip->addFile($src_file);
    $zip->close();
    print("Архив".$tgt_file." создан");
    exit(0);
    }

    пытаюсь вызвать так:


    include ("func.php");
    $src=".SourceFile.txt";
    $tgt=".TargetFile.zip";
    ZIPFile($src, $tgt);

    • А какая ошибка при этом появляется?
      Ошибка создания архива?
      Если да, то нужно проверить может ли вообще скрипт создать этот файл «.TargetFile.zip»? Попробуйте указать путь полностью.

    • VINTproYKT

      include «func.php» — гораздо лучше так. А если и происходит ошибка, её нужно бы описать…

  • Dockeee

    Попробовал немного видоизменить код — свести его в функцию, и архивировать отдельный файл, но ничего не выходит
    Сама функция (файл func.php):

    function ZIPFile($src_file, $tgt_file){
    $zip = new ZipArchive();
    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE!==true)) {
    print("Ошибка создания архива");
    exit(1);
    }
    $zip->addFile($src_file);
    $zip->close();
    print("Архив".$tgt_file." создан");
    exit(0);
    }

    пытаюсь вызвать так:


    include ("func.php");
    $src=".\SourceFile.txt";
    $tgt=".\TargetFile.zip";
    ZIPFile($src, $tgt);

    • А какая ошибка при этом появляется?
      Ошибка создания архива?
      Если да, то нужно проверить может ли вообще скрипт создать этот файл «.\TargetFile.zip»? Попробуйте указать путь полностью.

  • Dockeee

    Все. Попив кофе и отдохнув свежий взгляд нашол косяки.
    итак, разбор косяков:
    в строке

    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE!==true)) {

    закрывающая скобка должна стоять перед неравенством т.е. так:

    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE)!==true) {

    Далее.
    обычный косяк оставленный после экспериментов с путями — сделать так:

    $src="./SourceFile.txt";
    $tgt="./TargetFile.zip";

    и все заработало.

  • Dockeee

    Все. Попив кофе и отдохнув свежий взгляд нашол косяки.
    итак, разбор косяков:
    в строке

    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE!==true)) {

    закрывающая скобка должна стоять перед неравенством т.е. так:

    if ($zip->open($tgt_file, ZIPARCHIVE::CREATE)!==true) {

    Далее.
    обычный косяк оставленный после экспериментов с путями — сделать так:

    $src="./SourceFile.txt";
    $tgt="./TargetFile.zip";

    и все заработало.

  • Maxim

    Здравствуйте! У меня такой вопрос: Файл в архив добавляется след. образом $zip->addFile($filePath, $fileName). Можно ли в качестве $fileName передавалась строка с русским названием файла в архиве? И если можно, то как?(пробовал просто предать русскую строку но при открытии архива в качестве имён стоят козюбрики). Заранее спасибо за помощь!

    • Нет, раз у библиотеки есть проблемы с кириллицей, то лучше её не использовать. Если есть много файлов с русскими именами, то можно написать скрипт, который их переименует, например, транслитом.

  • Maxim

    Здравствуйте! У меня такой вопрос: Файл в архив добавляется след. образом $zip->addFile($filePath, $fileName). Можно ли в качестве $fileName передавалась строка с русским названием файла в архиве? И если можно, то как?(пробовал просто предать русскую строку но при открытии архива в качестве имён стоят козюбрики). Заранее спасибо за помощь!

    • Нет, раз у библиотеки есть проблемы с кириллицей, то лучше её не использовать. Если есть много файлов с русскими именами, то можно написать скрипт, который их переименует, например, транслитом.

  • prescott

    php_zip.dll — это только для венды, для линукса и уникса совсем по другому

    • Dockeee

      Да, и можно было об этом сказать. Зовется он либо php_zip.so либо просто zip.so
      Лежит в /usr/lib/php/modules/

  • prescott

    php_zip.dll — это только для венды, для линукса и уникса совсем по другому

    • Dockeee

      Да, и можно было об этом сказать. Зовется он либо php_zip.so либо просто zip.so
      Лежит в /usr/lib/php/modules/

  • Создал бы кто нибудь нормальный мануал по делению файлов в командной строке Putty по русски с примерами. Мануалы какие то кривые и сложные.

  • Создал бы кто нибудь нормальный мануал по делению файлов в командной строке Putty по русски с примерами. Мануалы какие то кривые и сложные.

  • Дмитрий

    Народ, как сделать так чтобы дотфайл не попадал в архив?

    • Просто не добавляйте его 🙂
      В этом примере я получаю файлы из папки с помощью readdir (строка 18). Она вернёт все файлы, находящиеся в папки. Просто вставьте внутрь цикла проверку, и пропускайте ненужные вам файлы.

      • Дмитрий

        понял, спасибо.

  • Дмитрий

    Народ, как сделать так чтобы дотфайл не попадал в архив?

    • Просто не добавляйте его 🙂
      В этом примере я получаю файлы из папки с помощью readdir (строка 18). Она вернёт все файлы, находящиеся в папки. Просто вставьте внутрь цикла проверку, и пропускайте ненужные вам файлы.

      • Дмитрий

        понял, спасибо.

  • Валерий

    Подскажите как запаковать папку со вложенными папками и файлами?

    • Можно написать рекурсивную функцию, которая будет обходить все папки начиная с заданной. Или использовать готовую библиотеку для этих целей. Второй вариант значительно проще 😉

    • Виталий

      Используем filetype() для рекурсии.

  • Валерий

    Подскажите как запаковать папку со вложенными папками и файлами?

    • Можно написать рекурсивную функцию, которая будет обходить все папки начиная с заданной. Или использовать готовую библиотеку для этих целей. Второй вариант значительно проще 😉

  • У меня не работало , пока не вставил
    if ($file != '.' and $file != '..')
    {
    $zip->addFile($src_dir.$file, $file);
    }
    Без этого скрипт выполнялся , а архив не создавался.

    • Виталий

      Если директории нужно опустить, можно просто использовать функцию filetype($src_dir.$file) если dir пропускаем если file добавляем.

  • Ralph DiMarko

    а можно ли как то запаролить архив?

  • Можно, смотрите <a
    href=»http://www.simplecoding.org/sozdanie-zip-arxivov-na-php.html#comment-49354161">этот
    комментарий

  • Ralph DiMarko

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

  • Боюсь, кроме тех. поддержки хостера вам никто не подскажет. Если речь о shared хостинге, то функция exec вообще может быть запрещена.

  • Derfid

    Про щебень в точку! Спасибо!

  • А как добавляются папки в архив и файлы в эти папки?

  • Нужно рекурсивно обойти все дерево папок. Пример здесь.

  • Pingback: Создание zip архивов с помощью PHP скрипта | Заметки обо всем()

  • Сергей Котельников

    А как узнать, запаролен ли архив (его файлы) или нет? в rar есть IsEncrypted

    • По-моему ZipArchive вообще не поддерживает работу с паролями.

  • Борис

    Warning: fwrite() expects parameter 1 to be resource, string given in Z:home192.168.0.42wwwupld_formmyformziparhive.php on line 24 Что хочет

    • Что у вас записано в 24-ой строке файла ziparhive.php?

  • byahvfnbr

    Как добавить в архив файл, содержащий в названии не только латиницу, но и символы как «Í» и другие?

    • Перекодируйте имя файла с помощью

      urlencode

  • Виталий

    В статье ошибочка. В месте, где указываем имя архива, в функции date() , параметр минут будет i а не m (указывает месяц)
    должно быть:
    $fileName = $archive_dir.»backup_».date('j_m_Y_h_i_s').».zip»

    В целом, гуд. Спасибо за потраченное время и экономию моего))

    • Спасибо, исправил.
      STDOUT — стандартный поток вывода. Если запускаете из консоли, вывод должен быть на экран.

  • Bokus

    я в код добавил

    while (false !== ($file = readdir($dirHandle))) { IF (is_file($src_dir.$file) ) {
    $zip->addFile($src_dir.$file, $file)
    }
    а то при попадании на . или на .. он архив не делал