Удаляем неактивные элементы из инфоблока и его разделов

(подходит как для «старого» ядра, так и для D7)

Удаление неактивных элементов из инфоблока
Коротко:
  1. Делайте бэкап БД.
  2. Проверяйте, что у вашего пользователя есть право на удаление.
  3. Тестируйте код на копии сайта.

1. Почему элементы «ACTIVE = N» лучше чистить вручную

  • Производительность. Чем меньше «мёртвых» записей, тем быстрее выборки.
  • UX в админке. Сотрудникам проще ориентироваться в списках.
  • SEO. Случайная переиндексация неактивных страниц = 404 + потеря краулингового бюджета.

2. Удаляем всё неактивное из инфоблока (старое ядро)


 $iblockId,
    'ACTIVE'    => 'N'
];

$res = CIBlockElement::GetList([], $arFilter, false, false, ['ID']);

while ($element = $res->Fetch())
{
    // true — успешное удаление, false — ошибка
    $result = CIBlockElement::Delete((int)$element['ID']);

    if(!$result)
    {
        global $APPLICATION;
        echo "Ошибка при удалении элемента #{$element['ID']}: "
             .$APPLICATION->LAST_ERROR."
"; } }

3. Удаляем неактивные элементы только из выбранных разделов (старое ядро)


 $iblockId,
    'SECTION_ID'  => $sectionIds,
    'ACTIVE'      => 'N',
    'INCLUDE_SUBSECTIONS' => 'Y'     // захватываем подразделы
];

$res = CIBlockElement::GetList([], $arFilter, false, false, ['ID']);

while ($el = $res->Fetch())
{
    CIBlockElement::Delete((int)$el['ID']);
}
        
Лайфхак: если нужен только один раздел без подразделов — уберите INCLUDE_SUBSECTIONS.

4. Современный способ на D7

4.1 Подготовка


use Bitrix\Iblock\Elements\ElementProductTable;   // пример: high‑level ORM‑класс
use Bitrix\Iblock\Iblock;                         // вспомогательный класс для таблиц
use Bitrix\Main\Loader;
use Bitrix\Main\ORM\Query\Query;

Loader::includeModule('iblock');
        

ElementProductTable - не забываем, что для использования такого класса, у вас должен быть определен соответствующий Символьный код API в настройках инфоблока. В конкретном случае - product. Если у вас она называется, к примеру, catalog, то именем класса будет ElementCatalogTable.

4.2 Удаляем из всего инфоблока


$iblockId = 7;

$iterator = ElementProductTable::query()
    ->setSelect(['ID'])
    ->where('IBLOCK_ID', $iblockId)
    ->where('ACTIVE', 'N')
    ->exec();

while ($row = $iterator->fetch())
{
    \CIBlockElement::Delete((int)$row['ID']);     // В D7 нет метода delete у ORM‑класса
}
        
Почему не $table::delete()? У ORM‑классов инфоблоков нет полноценного delete(), поэтому вызываем «старый» метод. Внутри 1С‑Битрикс он корректно удаляет файлы, свойства и записи в служебных таблицах.

4.3 Удаляем из конкретных разделов (D7 + Query)


$iblockId   = 7;
$sectionIds = [12, 18, 24];

$query = new Query(ElementProductTable::getEntity());
$query->setSelect(['ID'])
      ->where('IBLOCK_ID', $iblockId)
      ->where('ACTIVE', 'N')
      ->whereIn('IBLOCK_SECTION_ID', $sectionIds)
      ->registerRuntimeField(
          'SECTION',
          [
              'data_type' => '\Bitrix\Iblock\SectionTable',
              'reference' => ['=this.IBLOCK_SECTION_ID' => 'ref.ID'],
              'join_type' => 'INNER'
          ]
      );

$result = $query->exec();

while ($row = $result->fetch())
{
    CIBlockElement::Delete((int)$row['ID']);
}
        
Включаем подразделы D7‑ORM не умеет «из коробки» фильтровать по древовидной структуре. Нужно:
  1. Получить массив всех дочерних разделов через Bitrix\Iblock\SectionTable::getList() с фильтром по LEFT_MARGIN/RIGHT_MARGIN.
  2. Слить их в $sectionIds.
  3. Использовать whereIn() как выше.

5. Массовое удаление через CLI скрипт (cron)

Создайте файл /local/scripts/clear_inactive.php:


#!/usr/bin/php
<?php
$_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__.'/../../'); // путь к корню сайта
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

// … любой из приведённых выше методов …

echo "Готово\n";
?>

Права:


chmod +x /local/scripts/clear_inactive.php
        

Cron‑задание (раз в неделю ночью):


0 3 * * 1 /local/scripts/clear_inactive.php
        

6. Транзакции и производительность

  • Удалений много? Используйте Bitrix\Main\Application::getConnection()->startTransaction(); и коммитьте каждые ~100 элементов.
  • Нужна атомарность? Откатите транзакцию rollback() при первой ошибке.
  • Больше 5 000 элементов? Запускайте скрипт через CLI или php -d memory_limit=1G.

7. Частые ошибки

Ошибка Причина Решение
You don't have permission to delete element Нет прав группы Добавьте право «Удаление» в настройках инфоблока
Скрипт «висит» Ограничение max_execution_time Запускайте через CLI или увеличьте директиву
Удалены элементы, но не файлы Прямая работа через SQL Используйте только API Bitrix

8. Итоги

  • Старое ядро удобно, когда нужно быстро и «в лоб».
  • D7 даёт строгую типизацию, но пока не умеет удалять элементы напрямую — комбинируйте.
  • Обязательно логируйте ошибки и держите резервную копию.

Теперь у вас есть полный набор рецептов, чтобы держать инфоблоки в идеальном порядке и не хранить «мертвые души». Успешной оптимизации!

Теги:  инфоблок, удаление элементов, оптимизация, производительность, SEO, UX

Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Модули и компоненты для «1С-Битрикс»

оценка производится на основе предоставленного Технического Задания

от 20 000 рублей
Разработка дополнительных модулей для 1С-Битрикс, расширение функционала, внедрение любых решений, требующихся для выполнения ваших бизнес-задач.

* стоимость зависит от конкретной задачи, ее объема и сложности выполняемых работ.

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Техническая поддержка

выполняется с сайтами на основе любых CMS

от 5 000 рублей
Оптимизация производительности действующих интернет-проектов, наполнение и сопровождение, полная техническая поддержка и продвижение в поисковых сетях.

* стоимость зависит от объема и сложности выполняемых работ, используемой CMS.