Удаление неиспользуемых файлов Битрикс upload/iblock

Очистка неиспользуемых файлов в Bitrix: скрипт для директории /upload/iblock

Раздутие папки /upload/ в 1С-Битрикс — распространённая проблема. Для решения этой задачи я написал скрипт, который автоматизирует поиск и удаление неиспользуемых файлов в папке /upload/iblock. В статье разберём его работу, особенности использования и меры предосторожности.

Как работает скрипт

Код выполняет две ключевые задачи:

  1. Сравнивает файлы в файловой системе с записями в базе данных b_file Bitrix.
  2. Удаляет неиспользуемые файлы и директории

Архитектура решения:


$uploadPath = '/upload';
$subPath = '/iblock';
$isRemoveFiles = false;
$isRemoveDirs = false;

$rootDirPath = $_SERVER['DOCUMENT_ROOT'] . $uploadPath . $subPath;

// 1. Получаем файлы из базы данных с полными путями
$dbFiles = [];
$res = \Bitrix\Main\FileTable::getList([
    'select' => ['ID', 'SUBDIR', 'FILE_NAME'],
    'filter' => ['MODULE_ID' => 'iblock']
]);

while ($row = $res->fetch()) {
    $fullPath = str_replace($subPath, '', "/{$row['SUBDIR']}/{$row['FILE_NAME']}");
    $dbFiles[mb_strtolower($fullPath)] = $row['ID']; // Регистронезависимость
}

// 2. Рекурсивный обзор файловой системы
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator(
        $rootDirPath,
        FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS
    ),
    RecursiveIteratorIterator::CHILD_FIRST
);

$removedFiles = 0;
$removedDirs = 0;
$unusedFiles = 0;

foreach ($iterator as $path) {
    // 3. Пропускаем директории на первом проходе
    if ($path->isDir() || $path->isLink()) {
        continue;
    }

    $relativePath = mb_strtolower(str_replace($rootDirPath, '', $path->getPathname()));

    // 4. Проверка существования файла в БД
    if (!$dbFiles[$relativePath]) {
        $unusedFiles++;
        if ($isRemoveFiles) {
            if (@unlink($path->getPathname())) {
                $removedFiles++;
                echo "[DELETED] " . $path->getPathname() . PHP_EOL;
            } else {
                echo "[ERROR] Can't delete: " . $path->getPathname() . PHP_EOL;
            }
        } else {
            echo "[UNUSED_FILE] " . $path->getPathname() . PHP_EOL;
        }

    }
}

if ($isRemoveDirs) {
    // 5. Удаление пустых директорий (рекурсивно снизу вверх)
    foreach ($iterator as $path) {
        if ($path->isDir()) {
            $removedDirs++;
            echo "[REMOVED DIR] " . $path->getPathname() . PHP_EOL;
        }
    }
}


// 6. Статистика
echo PHP_EOL . "Итого:" . PHP_EOL;
echo "Отсканировано файлов: " . iterator_count($iterator) . PHP_EOL;
echo "Неиспользуемых файлов: " . $unusedFiles . PHP_EOL;
echo "Удалено файлов: $removedFiles" . PHP_EOL;
echo "Удалено директорий: $removedDirs" . PHP_EOL;

Инструкция по использованию

  1. Настройка параметров
    Измените переменные в начале скрипта:

    
    $uploadPath = '/custom_upload'; // Если используется нестандартный путь
    $isRemoveFiles = true;         // Активировать удаление
  2. Запуск в тестовом режиме
    Вывод списка неиспользуемых файлов без удаления:

    
    [UNUSED_FILE] /путь/к/upload/iblock/12a/example.jpg
    
  3. Активация очистки
    После проверки установите:

    
    $isRemoveFiles = true;
    $isRemoveDirs = true;
    
  4. Интерпретация результатов

    • [DELETED] — успешно удалённые файлы

    • [ERROR] — ошибки при удалении

    • [REMOVED DIR] — удалённые пустые директории

Меры предосторожности

  1. Обязательный бэкап
    Перед запуском создайте резервные копии:

    
    tar -czvf backup_$(date +%F).tar.gz /путь/к/site/upload/iblock
    
  2. Поэтапная активация
    Рекомендуемый порядок:

    • 1. Запуск в тестовом режиме
    • 2. Ручная проверка 10-20 случайных файлов из отчёта
    • 3. Активация удаления для файлов
    • 4. Удаление директорий (только после повторной проверки)
  3. Особые случаи
    Скрипт игнорирует:

    • - Символические ссылки (isLink())
    • - Системные файлы (.htaccess)
    • - Точечные директории (.git)

© 2026 MB

Desing by mb4design