Всем привет! Я нашел код для сжатия сайта в архив, однако он, почему-то, не архивирует папки в корне сайта, а только файлы. Можете подсказать, что может быть неправильно в этом коде? Вот он: <br/><br/><pre><code class="php"><?php
$zip = new ZipArchive();
$filename = "myzipfile.zip";
if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
exit("cannot open <$filename>\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 != '' && $file != '.' && $file != '..'){
$zip->addFile($dir.$file);
}
}
}
closedir($dh);
}
}
$zip->close();
echo $filename;</code></pre>
Ваш код действительно добавляет только файлы на верхнем уровне директории, но пропускает поддиректории (папки) и их содержимое. Чтобы исправить это, вам нужно рекурсивно просмотреть все папки и добавлять файлы в архив.
Ниже приведён пример исправленного кода, который обрабатывает поддиректории:
```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->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>