Очистка неиспользуемых файлов в Bitrix: скрипт для директории /upload/iblock
Раздутие папки /upload/ в 1С-Битрикс — распространённая проблема. Для решения этой задачи я написал скрипт, который автоматизирует поиск и удаление неиспользуемых файлов в папке /upload/iblock. В статье разберём его работу, особенности использования и меры предосторожности.
Как работает скрипт
Код выполняет две ключевые задачи:
- Сравнивает файлы в файловой системе с записями в базе данных b_file Bitrix.
- Удаляет неиспользуемые файлы и директории
Архитектура решения:
$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;
Инструкция по использованию
-
Настройка параметров
Измените переменные в начале скрипта:$uploadPath = '/custom_upload'; // Если используется нестандартный путь $isRemoveFiles = true; // Активировать удаление -
Запуск в тестовом режиме
Вывод списка неиспользуемых файлов без удаления:[UNUSED_FILE] /путь/к/upload/iblock/12a/example.jpg -
Активация очистки
После проверки установите:$isRemoveFiles = true; $isRemoveDirs = true; -
Интерпретация результатов
-
[DELETED]— успешно удалённые файлы -
[ERROR]— ошибки при удалении -
[REMOVED DIR]— удалённые пустые директории
-
Меры предосторожности
-
Обязательный бэкап
Перед запуском создайте резервные копии:tar -czvf backup_$(date +%F).tar.gz /путь/к/site/upload/iblock -
Поэтапная активация
Рекомендуемый порядок:- 1. Запуск в тестовом режиме
- 2. Ручная проверка 10-20 случайных файлов из отчёта
- 3. Активация удаления для файлов
- 4. Удаление директорий (только после повторной проверки)
-
Особые случаи
Скрипт игнорирует:-
- Символические ссылки (
isLink()) -
- Системные файлы (
.htaccess) -
- Точечные директории (
.git)
-
- Символические ссылки (