Для роботи із ZIP я зберіг посилання на http://blog.webmasterschool.ru/php/48/ та клас Create ZIP File з http://www.phpclasses.org. Нижче — приклади роботи зі старим стороннім класом і процедурним ZIP API.
Створення архіву
Клас createZip не є вбудованим класом PHP. Його реалізації у статті немає; приклад залежить від окремого файла createZip.inc.php:
// Подключаем класс для работы с zip-архивами
include_once("createZip.inc.php");
$createZip = new createZip;
// Добавляем директорию
$createZip -> addDirectory("dir/");
// Добавляем файл
$fileContents = file_get_contents("img.jpg");
$createZip -> addFile($fileContents, "dir/img.jpg");
// Создаем архив
$fileName = "archive.zip";
$fd = fopen ($fileName, "wb");
$out = fwrite ($fd, $createZip -> getZippedfile());
fclose ($fd);
// Отдаем архив браузеру
$createZip -> forceDownload($fileName);
@unlink($fileName);
?>Функція розпакування та її параметри
У прикладі $dir задає каталог призначення, $file — шлях до архіву, а $log вмикає діагностичний вивід. Функція проходить елементи архіву, створює каталоги та записує вміст файлів:
/**
* Распаковывает zip-архив в указанный каталог.
* $dir - полный путь к каталогу.
* $file - полный путь к zip-архиву.
* $log - флаг вывода диагностики.
*/
function unpackZip($dir, $file, $log=0) {
if ($log) echo "Start unpack [$file] into [$dir] directory...
";
if ($zip = zip_open($file)) {
if ($zip) {
// создать каталог, если он не существует
if (! file_exists($dir)) mkdir($dir);
while ($zip_entry = zip_read($zip)) {
$name = zip_entry_name($zip_entry);
if ($log) echo " <b>unpack </b>: $name
";
// последний символ имени
$last = substr($name, strlen($name)-1);
// если это каталог
if ($last == "/" || $last == "\\") {
$subdir = $dir."/".$name;
// создать каталог, если он не существует
if (! file_exists($subdir)) mkdir ($subdir);
} else {
// распаковать файл
if (zip_entry_open($zip, $zip_entry, "r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
$fp = fopen($dir."/".zip_entry_name($zip_entry), "w");
fwrite($fp, $buf);
zip_entry_close($zip_entry);
} else {
return false;
}
}
}
zip_close($zip);
}
} else {
return false;
}
return true;
}
?>Що потрібно врахувати перед використанням
Ці фрагменти не є готовим рішенням для обробки недовірених архівів. У функції шлях запису складається безпосередньо з імені елемента ZIP: немає перевірки виходу за межі каталогу, обмежень обсягу розпакування чи надійного контролю помилок. Дескриптор записуваного файла явно не закривається; вкладені каталоги також обробляються неповно.
Крім того, zip_open() може повертати числовий код помилки, тому проста перевірка істинності не гарантує успішного відкриття. Цю функцію позначено застарілою з PHP 8.0 на користь об'єктного API ZipArchive.
Для нового коду звертайтеся до документації ZipArchive та перевіряйте шляхи, ліміти ресурсів і всі результати операцій. Довідка щодо старого виклику: zip_open. Історичний код збережено для розбору; не запускайте його без адаптації на довільних завантаженнях.
Немає коментарів:
Дописати коментар