Как создать ZIP-архив из файлов сайта?

Всем привет! Я нашел код для сжатия сайта в архив, однако он, почему-то, не архивирует папки в корне сайта, а только файлы. Можете подсказать, что может быть неправильно в этом коде? Вот он: <br/><br/><pre><code class="php">&lt;?php

$zip = new ZipArchive();
$filename = "myzipfile.zip";

if ($zip-&gt;open($filename, ZipArchive::CREATE)!==TRUE) {
        exit("cannot open &lt;$filename&gt;\n");
}

$dir = './';

// Create zip
if (is_dir($dir)){

    if ($dh = opendir($dir)){
        while (($file = readdir($dh)) !== false){
                
            // If file
            if (is_file($dir.$file)) {
                if($file != '' &amp;&amp; $file != '.' &amp;&amp; $file != '..'){
                        
                    $zip-&gt;addFile($dir.$file);
                }
            }
                    
        }
        closedir($dh);
    }
}

$zip-&gt;close();

echo $filename;</code></pre>
  • 16 декабря 2024 г. 18:13
Ответы на вопрос 3
Ваш код действительно добавляет только файлы на верхнем уровне директории, но пропускает поддиректории (папки) и их содержимое. Чтобы исправить это, вам нужно рекурсивно просмотреть все папки и добавлять файлы в архив.

Ниже приведён пример исправленного кода, который обрабатывает поддиректории:

```php
<?php

$zip = new ZipArchive();
$filename = "myzipfile.zip";

if ($zip->open($filename, ZipArchive::CREATE) !== TRUE) {
    exit("cannot open <$filename>\n");
}

$dir = './';

// Функция для рекурсивного добавления файлов и папок в архив
function addFilesToZip($dir, $zip, $deep_dir) {
    if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
            while (($file = readdir($dh)) !== false) {
                if ($file != '.' && $file != '..') {
                    if (is_dir($dir . $file)) {
                        // Если это директория, рекурсивно добавляем содержимое
                        addFilesToZip($dir . $file . '/', $zip, $deep_dir . $file . '/');
                    } else {
                        // Если это файл, добавляем его в архив
                        $zip->addFile($dir . $file, $deep_dir . $file);
                    }
                }
            }
            closedir($dh);
        }
    }
}

// Добавляем файлы и папки в архив
addFilesToZip($dir, $zip, '');

// Закрываем архив
$zip->close();

echo $filename;
```

### Объяснение изменений:

1. **Рекурсивная функция** `addFilesToZip`: Эта функция сканирует указанную директорию:
   - Если в найденный элемент — директорий, она вызывается рекурсивно.
   - Если это файл, он добавляется в архив.

2. **Параметры функции**: При каждом рекурсивном вызове мы передаём текущее состояние директории и путь к файлу, чтобы сохранить иерархию файлов в архиве.

Таким образом, ваш архив будет корректно включать как файлы, так и папки с их содержимым.
Потому, что у вас в коде происходит обход только по текущему уровню каталога $dir. <br/> Чтобы обход заныривал глубже, нужно создать рекурсивную функцию. <br/> Телом рекурсивной функции у вас будет: <br/> <pre><code class="php">if ($dh = opendir($dir))
{
// код, который у вас в вопросе
}</code></pre> <br/> А точка вызова для смены подкаталога: <br/> <pre><code class="php">if (is_file($dir.$file)) {
// код из вопроса
            }
else if(is_dir($dir.$file))
{
   $zip-&gt;addDir($dir.$file);
   // тут должен быть вызов рекурсивной функции, по которой вы передаете контекст $zip и $dir.$file (наверное, передача по ссылке)
}</code></pre> <br/> В этом случае у вас будет рекурсивный обход каталогов в глубину. <br/> PS: Проконтролируйте дескриптор $zip на больших вложенностях и большим содержании файлов, нет ли переполнения выделенной оперативной памяти. Еще стек вызовов функций не бесконечный, тоже проконтролируйте глубину вызова. <br/> PPS: Бэкапить сайты в архив делается одной строчкой линуксовой командой, и засовывается в crontab. Будет работать надежнее. Эта не задачка для php-разработчика. <br/> То, что вы делаете - это просто тренировка на кошках, как работать с ZipArchive в PHP.
Пттому что метод addFile добавляет файл к архиву, а не каталог. (да и у стандартного zip надо указывать, что хотим заходить в каталог) <br/> Либо Вам надо самому писать обход подкаталогов, либо воспользоваться другим методом добавления файлов в архив, изучив документацию. <br/> <a href="https://www.php.net/manual/en/class.ziparchive.php" rel="nofollow">https://www.php.net/manual/en/class.ziparchive.php</a>
Похожие вопросы