DEV Community

Андрей Викулов (VProger)
Андрей Викулов (VProger)

Posted on • Originally published at viku-lov.ru on

Aspro SmartSEO падает после обновления Битрикс: фикс getRowById одной командой

Падение 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 = [])

Enter fullscreen mode Exit fullscreen mode

Проявления на проекте:

  • страницы каталога и умного фильтра возвращают HTTP 500;
  • SEO-страницы, сгенерированные SmartSEO, не открываются;
  • в логах php_error.log — фатал без возможности graceful fallback;
  • кеш не спасает, потому что выполнение падает до логики модуля.

Важно: ошибка возникает не в пользовательском коде, а внутри модуля SmartSEO, поэтому «поправить компонент» или «переустановить шаблон» не помогает.


Почему это происходит на самом деле

Ключевой момент — ORM и наследование

В основе проблемы лежит метод:


Bitrix\Main\ORM\Data\DataManager::getRowById()

Enter fullscreen mode Exit fullscreen mode

В актуальных версиях ядра его сигнатура выглядит так:


public static function getRowById($id, array $parameters = [])

Enter fullscreen mode Exit fullscreen mode

Параметр $parameters используется ORM для передачи дополнительных условий выборки, runtime-полей, select и других параметров запроса.

Что делает Aspro SmartSEO

Модуль SmartSEO содержит собственные ORM-таблицы в пространстве имён:


Aspro\Smartseo\Models\*

Enter fullscreen mode Exit fullscreen mode

Эти классы наследуются от DataManager, но в ряде файлов метод getRowById был переопределён с устаревшей сигнатурой:


public static function getRowById($id)

Enter fullscreen mode Exit fullscreen mode

Это прямое нарушение правил совместимости методов в PHP:

Если метод переопределяется в дочернем классе, его сигнатура должна быть совместима с родительской.

Ранее это не вызывало ошибок либо из-за более мягких проверок, либо из-за того, что код не исполнялся в критических сценариях. После обновления ядра проверка стала строгой — и PHP закономерно завершает выполнение с fatal error.


Почему это не «мелкий баг», а архитектурная ошибка

Здесь важно зафиксировать:

проблема не в обновлении Битрикс.

Ядро действует корректно:

  • метод getRowById расширен;
  • обратная совместимость соблюдена;
  • сигнатура официальная и используется ORM.

Ошибка — в модуле, который:

  • наследуется от DataManager;
  • переопределяет метод;
  • не обновляет сигнатуру под родителя.

Это означает, что ошибка гарантированно будет всплывать и дальше, при любых последующих изменениях ORM.


Корректное решение: патч сигнатуры и вызова родителя

Решение должно делать две вещи:

  1. Привести сигнатуру метода в дочерних классах к совместимой.
  2. Корректно прокинуть $parameters в вызов родительского метода.

Важный принцип

Мы не ломаем API, не меняем логику выборки, не добавляем костылей.

Мы всего лишь приводим код модуля в соответствие с контрактом родительского класса.


Шаг 1. Исправление сигнатуры getRowById

Необходимо во всех моделях SmartSEO заменить:


function getRowById($id)

Enter fullscreen mode Exit fullscreen mode

на:


function getRowById($id, array $parameters = [])

Enter fullscreen mode Exit fullscreen mode

Практически и безопасно это делается одной командой, без ручного редактирования файлов:


perl -0777 -i -pe 's/function\s+getRowById\s<i>\(\s</i>\$id\s\*\)/function getRowById(\$id, array \$parameters = [])/g' \

bitrix/modules/aspro.smartseo/lib/models/\*.php

Enter fullscreen mode Exit fullscreen mode

Проверка результата


grep -R "function getRowById" -n bitrix/modules/aspro.smartseo/lib/models/

Enter fullscreen mode Exit fullscreen mode

Ожидаемый вид:


public static function getRowById($id, array $parameters = []) {

Enter fullscreen mode Exit fullscreen mode

Шаг 2. Исправление вызова parent::getRowById

В ряде моделей внутри метода используется вызов:


parent::getRowById($id)

Enter fullscreen mode Exit fullscreen mode

После изменения сигнатуры это уже некорректно, так как $parameters теряются.

Поиск проблемных мест


grep -R "parent::getRowById\s\*(" -n bitrix/modules/aspro.smartseo/lib/models/

Enter fullscreen mode Exit fullscreen mode

Массовый патч


perl -0777 -i -pe 's/parent::getRowById\s<i>\(\s</i>\$id\s\*\)/parent::getRowById(\$id, \$parameters)/g' \

bitrix/modules/aspro.smartseo/lib/models/\*.php

Enter fullscreen mode Exit fullscreen mode

Ожидаемый результат


$data = parent::getRowById($id, $parameters);

Enter fullscreen mode Exit fullscreen mode

Это полностью соответствует контракту ORM и не меняет бизнес-логику модуля.


Шаг 3. Очистка кеша Битрикс

Даже корректный код не заработает, если Битрикс продолжает использовать старые кешированные данные.

Обязательный шаг:


rm -rf bitrix/cache/<i> bitrix/managed\_cache/</i>

Enter fullscreen mode Exit fullscreen mode

После этого фатальные ошибки исчезают, а SmartSEO начинает работать штатно.


Что именно исправляет этот патч

  • устраняет фатальную ошибку PHP;
  • восстанавливает работу каталога и SEO-страниц;
  • делает модуль совместимым с текущей и будущими версиями ORM;
  • не влияет на данные, структуру БД и настройки проекта.

Это не временный «костыль», а приведение модуля в корректное состояние.


Почему именно такое решение — правильное

  1. Соответствует ООП-контракту

Мы не подавляем ошибку, а устраняем её причину.

  1. Минимальное вмешательство

Меняется только сигнатура и прокидывание параметров.

  1. Воспроизводимость

Решение можно повторить на любом сервере и проекте.

  1. Безопасность

Нет влияния на данные, миграции, кеш-ключи, SEO-логику.


Вывод

Ошибка SmartSEO после обновления Битрикс — не «случайный баг», а результат устаревшего кода модуля, который долгое время нарушал контракт ORM.

Обновление ядра лишь сделало проблему видимой.

Правильный подход в таких ситуациях:

  • не откатывать ядро;
  • не править код вручную «на глаз»;
  • не маскировать ошибку.

А приводить сигнатуры методов в соответствие с родительскими классами.

Именно это и делает описанный патч.


Если нужно — дальше можно разобрать, как автоматизировать такие проверки для модулей или как отслеживать подобные несовместимости до выхода в прод. Но это уже отдельная инженерная тема.

Read more on viku-lov.ru

Top comments (0)