Aspro SmartSEO падает после обновления Битрикс: фикс getRowById одной командой
После обновления 1С-Битрикс модуль Aspro SmartSEO может падать с fatal из-за несовместимой сигнатуры getRowById. Разбираем причину и даём безопасный патч в 3 шага.
Требования
- Доступ по SSH к серверу с проектом (BitrixVM/обычный Linux)
- Утилиты grep + perl (обычно есть на сервере)
- Понимание где лежит /bitrix/modules/
Падение Aspro SmartSEO после обновления Битрикс: разбор причины и корректный фикс сигнатуры getRowById
Обновления ядра 1С-Битрикс нередко выявляют слабые места сторонних модулей. Летом–осенью 2025 года на ряде проектов проявилась критическая ошибка в модуле Aspro SmartSEO, из-за которой сайты начинали отдавать 500-е ошибки, переставал работать каталог, переставали работать SEO-фильтры и связанные страницы.
На первый взгляд проблема выглядит как «очередной баг обновления». На практике — это классический пример нарушения контракта наследования в PHP, который долгое время оставался незаметным и «взорвался» после очередных изменений ORM ядра.
В этой статье:
- разберём реальную причину ошибки, а не симптомы;
- покажем, почему она проявилась именно сейчас;
- приведём корректное и воспроизводимое решение, применённое на рабочем проекте;
- объясним, что именно чинит каждая правка и почему она безопасна.
Симптомы проблемы
После обновления ядра Битрикс сайт начинает падать с фатальной ошибкой PHP. Типичный текст ошибки выглядит так:
Fatal error: Declaration of Aspro\Smartseo\Models\SmartseoFilterRuleTable::getRowById($id)
must be compatible with Bitrix\Main\ORM\Data\DataManager::getRowById($id, array $parameters = [])
Проявления на проекте:
- страницы каталога и умного фильтра возвращают HTTP 500;
- SEO-страницы, сгенерированные SmartSEO, не открываются;
- в логах
php_error.log— фатал без возможности graceful fallback; - кеш не спасает, потому что выполнение падает до логики модуля.
Важно: ошибка возникает не в пользовательском коде, а внутри модуля SmartSEO, поэтому «поправить компонент» или «переустановить шаблон» не помогает.
Почему это происходит на самом деле
Ключевой момент — ORM и наследование
В основе проблемы лежит метод:
Bitrix\Main\ORM\Data\DataManager::getRowById()
В актуальных версиях ядра его сигнатура выглядит так:
public static function getRowById($id, array $parameters = [])
Параметр $parameters используется ORM для передачи дополнительных условий выборки, runtime-полей, select и других параметров запроса.
Что делает Aspro SmartSEO
Модуль SmartSEO содержит собственные ORM-таблицы в пространстве имён:
Aspro\Smartseo\Models\*
Эти классы наследуются от DataManager, но в ряде файлов метод getRowById был переопределён с устаревшей сигнатурой:
public static function getRowById($id)
Это прямое нарушение правил совместимости методов в PHP:
Если метод переопределяется в дочернем классе, его сигнатура должна быть совместима с родительской.
Ранее это не вызывало ошибок либо из-за более мягких проверок, либо из-за того, что код не исполнялся в критических сценариях. После обновления ядра проверка стала строгой — и PHP закономерно завершает выполнение с fatal error.
Почему это не «мелкий баг», а архитектурная ошибка
Здесь важно зафиксировать: проблема не в обновлении Битрикс.
Ядро действует корректно:
- метод
getRowByIdрасширен; - обратная совместимость соблюдена;
- сигнатура официальная и используется ORM.
Ошибка — в модуле, который:
- наследуется от
DataManager; - переопределяет метод;
- не обновляет сигнатуру под родителя.
Это означает, что ошибка гарантированно будет всплывать и дальше, при любых последующих изменениях ORM.
Корректное решение: патч сигнатуры и вызова родителя
Решение должно делать две вещи:
- Привести сигнатуру метода в дочерних классах к совместимой.
- Корректно прокинуть
$parametersв вызов родительского метода.
Важный принцип
Мы не ломаем API, не меняем логику выборки, не добавляем костылей. Мы всего лишь приводим код модуля в соответствие с контрактом родительского класса.
Шаг 1. Исправление сигнатуры getRowById
Необходимо во всех моделях SmartSEO заменить:
function getRowById($id)
на:
function getRowById($id, array $parameters = [])
Практически и безопасно это делается одной командой, без ручного редактирования файлов:
perl -0777 -i -pe 's/function\s+getRowById\s*\(\s*\$id\s*\)/function getRowById(\$id, array \$parameters = [])/g' \
bitrix/modules/aspro.smartseo/lib/models/*.php
Проверка результата
grep -R "function getRowById" -n bitrix/modules/aspro.smartseo/lib/models/
Ожидаемый вид:
public static function getRowById($id, array $parameters = []) {
Шаг 2. Исправление вызова parent::getRowById
В ряде моделей внутри метода используется вызов:
parent::getRowById($id)
После изменения сигнатуры это уже некорректно, так как $parameters теряются.
Поиск проблемных мест
grep -R "parent::getRowById\s*(" -n bitrix/modules/aspro.smartseo/lib/models/
Массовый патч
perl -0777 -i -pe 's/parent::getRowById\s*\(\s*\$id\s*\)/parent::getRowById(\$id, \$parameters)/g' \
bitrix/modules/aspro.smartseo/lib/models/*.php
Ожидаемый результат
$data = parent::getRowById($id, $parameters);
Это полностью соответствует контракту ORM и не меняет бизнес-логику модуля.
Шаг 3. Очистка кеша Битрикс
Даже корректный код не заработает, если Битрикс продолжает использовать старые кешированные данные.
Обязательный шаг:
rm -rf bitrix/cache/* bitrix/managed_cache/*
После этого фатальные ошибки исчезают, а SmartSEO начинает работать штатно.
Что именно исправляет этот патч
- устраняет фатальную ошибку PHP;
- восстанавливает работу каталога и SEO-страниц;
- делает модуль совместимым с текущей и будущими версиями ORM;
- не влияет на данные, структуру БД и настройки проекта.
Это не временный «костыль», а приведение модуля в корректное состояние.
Почему именно такое решение — правильное
-
Соответствует ООП-контракту Мы не подавляем ошибку, а устраняем её причину.
-
Минимальное вмешательство Меняется только сигнатура и прокидывание параметров.
-
Воспроизводимость Решение можно повторить на любом сервере и проекте.
-
Безопасность Нет влияния на данные, миграции, кеш-ключи, SEO-логику.
Вывод
Ошибка SmartSEO после обновления Битрикс — не «случайный баг», а результат устаревшего кода модуля, который долгое время нарушал контракт ORM.
Обновление ядра лишь сделало проблему видимой.
Правильный подход в таких ситуациях:
- не откатывать ядро;
- не править код вручную «на глаз»;
- не маскировать ошибку.
А приводить сигнатуры методов в соответствие с родительскими классами.
Именно это и делает описанный патч.
Если нужно — дальше можно разобрать, как автоматизировать такие проверки для модулей или как отслеживать подобные несовместимости до выхода в прод. Но это уже отдельная инженерная тема.



Комментарии