CMS: WordPress, Битрикс, Tilda и другие

Обновление плагинов сломало сайт: как найти виновника и откатиться

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

11 минут чтения 3 Дмитрий Акиндинов
Содержание
  1. Сначала поднять, потом разбираться
  2. Откат плагина на предыдущую версию
  3. Ищем виновника методом половинного деления
  4. Конфликт с темой или баг в самом плагине
  5. Фатальные ошибки PHP после обновления
  6. Как обновляться дальше, чтобы не повторилось
  7. Что писать в журнал работ
  8. Короткий чек-лист на случай аварии
  9. Частые вопросы

Сначала поднять сайт, потом искать виновника. Поднимают откатом плагина на предыдущую версию или разворачиванием вчерашней копии. Виновника среди двадцати обновлённых плагинов ищут делением пополам, а не перебором по одному.

Утро, клиент пишет «сайт не открывается». Открываешь: белый экран, иногда ошибка 500, иногда половина страницы и обрыв на середине. Накануне кто-то зашёл в админку и нажал «Обновить все» на двадцати плагинах разом. Ситуация, когда обновление плагинов сломало сайт, у меня в работе идёт вторым номером по частоте после взломов. Ниже рабочий порядок: как поднять сайт за десять минут, как вычислить виновника, даже если обновилось сразу двадцать штук, и что настроить, чтобы через квартал не повторилось.

Блок плагина выпадает из стопки, рядом стрелка отката к предыдущей версии

Сначала поднять, потом разбираться

Инженерный инстинкт говорит: полезай в логи, пойми причину. Инстинкт верный, момент неверный. Пока вы читаете стектрейс, сайт лежит, контекстная реклама сливает бюджет в 500-ю ошибку, а клиент набирает вас каждые пять минут и мешает думать.

Порядок другой. Вернуть рабочее состояние. Сохранить копию сломанного. Разбираться уже на копии, спокойно.

Три способа поднять сайт, от быстрого к медленному:

  1. Отключить все плагины разом. Полминуты работы, сайт встаёт почти всегда.
  2. Откатить конкретный плагин на предыдущую версию. Две-пять минут, если вы уже знаете, какой именно виноват.
  3. Развернуть вчерашний бэкап. От десяти минут до часа, и вы теряете заказы, комментарии и правки за сегодня.

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

Когда админка не открывается

Белый экран обычно закрывает и /wp-admin/ тоже, поэтому кнопки «деактивировать» вы не увидите. WordPress считает плагин активным по записи в таблице wp_options (опция active_plugins), но при загрузке проверяет наличие файла. Нет файла, нет и загрузки.

Самый быстрый приём по SSH:

cd /var/www/site/wp-content
mv plugins plugins.off && mkdir plugins

Сайт откроется голым: тема без функционала, формы не работают, кэш не собирается. Зато открывается, и вы попадаете в админку. Через FTP то же самое делается переименованием папки plugins в файловом менеджере хостинга.

Если WP-CLI на хостинге есть, сделайте аккуратнее, чтобы потом не гадать, что было включено:

wp plugin list --status=active --field=name > ~/active-plugins.txt
wp plugin deactivate --all

Файл active-plugins.txt дальше пригодится для поиска виновника. Без него вы рискуете забыть, что на сайте вообще-то был включён плагин выгрузки в Яндекс Маркет, и обнаружить это через неделю по звонку из отдела продаж.

Откат плагина на предыдущую версию

Откат это не магия, а подмена папки. У каждого плагина из официального каталога WordPress все прошлые версии лежат по прямым ссылкам, ничего искать по форумам не нужно.

Через файлы

cd /var/www/site/wp-content/plugins
mv contact-form-7 contact-form-7.broken
wget https://downloads.wordpress.org/plugin/contact-form-7.5.9.8.zip
unzip contact-form-7.5.9.8.zip
rm contact-form-7.5.9.8.zip

Схема имени файла простая: plugin/<slug>.<версия>.zip. Slug берётся из URL плагина в каталоге wordpress.org. Старую папку не удаляйте, а переименовывайте: в ней могли осесть пользовательские файлы, шаблоны писем или загрузки.

Через WP-CLI

wp plugin install contact-form-7 --version=5.9.8 --force
wp plugin activate contact-form-7

Ключ --force обязателен, иначе WP-CLI увидит уже установленный плагин и вежливо откажется его трогать. После установки проверьте, что версия действительно та:

wp plugin list --fields=name,status,version,update_version

Через админку

Плагин WP Rollback, бесплатный, добавляет ссылку «Rollback» рядом с каждым плагином из каталога. Выбираете версию из списка, жмёте, готово. Для владельца сайта без SSH это лучший вариант, держите его установленным заранее. Ставить WP Rollback в момент аварии бессмысленно: админка уже не открывается.

Что делать с платными плагинами

ACF PRO, WP Rocket, Elementor Pro, WPML, Gravity Forms в публичном каталоге не лежат. Их старые версии качаются только из личного кабинета разработчика, и не у всех архив открыт: у части вендоров доступны последние две-три версии, дальше пусто.

Отсюда правило, которое я держу у всех клиентов на абонентке: перед обновлением платного плагина ZIP текущей версии складывается в отдельную папку вне сайта. Занимает полминуты, экономит вечер. У меня для этого на сервере просто каталог ~/plugin-archive/ с именами вида acf-pro-6.3.11.zip.

Ищем виновника методом половинного деления

Ситуация: обновилось двадцать плагинов, сайт лёг, какой именно виноват, неизвестно. Перебирать по одному это двадцать итераций, каждая с проверкой страниц. Половинное деление сокращает это до пяти.

Логика та же, что при поиске коммита через git bisect. Включаете половину, смотрите, воспроизводится ли поломка, дальше делите ту половину, где сломалось.

# все выключены, включаем первые 10 из списка
wp plugin activate $(head -10 ~/active-plugins.txt | tr 'n' ' ')
curl -s -o /dev/null -w "%{http_code}n" https://site.ru/

Реальный прогон на двадцати плагинах выглядит так:

ШагВключеноОтвет главнойВывод
1плагины 1-10200виновник во второй десятке
21-10 плюс 11-15500виновник среди 11-15
31-10 плюс 11-12200виновник среди 13-15
41-10 плюс 11-13500виновник это плагин 13
5всё, кроме 13200подтверждено

Пять проверок вместо двадцати. На каждом шаге проверяйте не только главную: поломка часто сидит на конкретном шаблоне. Мой минимальный набор для curl это главная, страница услуги, карточка товара, страница корзины, страница блога и /wp-admin/. Код 200 на главной при 500 на корзине это не победа, а неточная диагностика.

Отдельная оговорка про кэш. Если на сайте стоит LiteSpeed Cache, WP Super Cache или кэш на стороне хостинга, вы будете получать 200 со старой страницы и радоваться зря. Перед проверкой чистите кэш (wp cache flush, кнопка в панели) или ходите на URL с случайным параметром вида ?nocache=1.

Конфликт с темой или баг в самом плагине

Половинное деление даёт вам плагин, после включения которого сайт падает. Это ещё не значит, что плагин плохой. В моей практике примерно в трети случаев виноват не он, а связка.

Что стоит проверить, прежде чем писать разработчику плагина гневное письмо:

  • Включите проблемный плагин при стандартной теме. wp theme activate twentytwentyfive, проверьте страницу, верните свою тему обратно. Если при дефолтной теме всё работает, дело в теме или в её functions.php.
  • Проверьте, нет ли в теме или в дочерней теме своих хуков на функции плагина. Ищется грепом: grep -rn "acf_add_local_field_group" wp-content/themes/.
  • Посмотрите, не обновилось ли одновременно два плагина, которые лезут в одно и то же. Два кэширующих плагина, два SEO-плагина, два оптимизатора картинок конфликтуют почти гарантированно.
  • Проверьте, не переопределяет ли ваш сайт шаблоны плагина. Классика WooCommerce: файлы из plugins/woocommerce/templates/ скопированы в тему, плагин обновился, шаблон в теме остался от версии 8.х и вызывает функцию, которой больше нет.

Последний пункт даёт больше всего поломок на магазинах. WooCommerce честно пишет в разделе Status, что шаблоны устарели, но эту страницу владелец сайта не открывает никогда.

Если после всех проверок падение воспроизводится на голой теме и с одним включённым плагином, это баг вендора. Тогда откатывайтесь, ставьте плагин в исключения автообновлений и ждите следующего релиза. Ждать обычно приходится от нескольких дней до двух недель, за это время в трекере плагина на wordpress.org уже появляется ветка с вашей ошибкой.

Фатальные ошибки PHP после обновления

Второй большой класс поломок это несовместимость версии PHP. Плагин выпустил мажорную версию, поднял минимальные требования до PHP 8.1, а у вас на хостинге 7.4 с 2020 года. Подробнее про сам переход я разбирал в статье про белый экран смерти в WordPress, тут только про диагностику.

Сначала включите лог. В wp-config.php выше строки с комментарием про «That’s all, stop editing»:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);

Ошибки лягут в wp-content/debug.log. WP_DEBUG_DISPLAY в false нужен, чтобы посетители не читали ваши пути на сервере. После разбора обязательно верните WP_DEBUG в false, иначе лог за месяц раздуется до сотен мегабайт и съест квоту хостинга.

Что там обычно видно и о чём это говорит:

Строка в логеПричинаЧто делать
Call to undefined function str_contains()плагин собран под PHP 8.0+, у вас 7.4поднять PHP или откатить плагин
Cannot redeclare functionдва плагина объявили одноимённую функциюотключить один, писать вендору
Allowed memory size exhaustedне хватило памяти после обновленияWP_MEMORY_LIMIT до 256M, проверить лимиты хостинга
Uncaught TypeError: ... must be of type array, null givenбаг вендора или битые данные в БДоткат версии
Deprecated: Creation of dynamic propertyплагин старый, PHP 8.2+не фатально, но плагин пора менять

Проверить требования заранее можно без всякого запуска. Каждый плагин пишет их в шапке главного файла:

grep -H "Requires PHP" wp-content/plugins/*/*.php | sort -u
php -v

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

Как обновляться дальше, чтобы не повторилось

Вечная позиция «не трогай, пока работает» заканчивается тем, что на сайте копится сорок апдейтов и две мажорных версии ядра, а потом всё это накатывается разом и ломает всё разом. Тонкости самого процесса я разбирал в материале про обновление WordPress без поломок, тут дам короткий рабочий регламент.

Тестовая копия

Копия сайта на поддомене вида staging.site.ru, закрытая от индексации и от посторонних. Все обновления сначала туда, проверка ключевых сценариев, потом на боевой. Стоит это порядка 200-400 рублей в месяц на shared-хостинге, разворачивается за час. Как это делается дёшево, я описывал в статье про staging для маленького сайта.

Для визитки на пять страниц staging избыточен, соглашусь. Для магазина или сайта с формами и интеграциями он окупается первым же несостоявшимся простоем.

Пачками, а не всё сразу

Двадцать плагинов за один клик это удобно ровно до первой аварии. Дальше начинается то, ради чего написана половина этой статьи. Обновляйте по три-пять штук за подход, между подходами проверяйте главную и одну-две ключевые страницы. Занимает лишние десять минут, экономит вечер.

Порядок обновления, который я держу у себя:

  1. Бэкап файлов и базы, обязательно с проверкой, что архив скачался.
  2. Плагины безопасности и антиспама.
  3. Всё остальное пачками, начиная с самых мелких и безобидных.
  4. Тяжёлые: конструкторы страниц, WooCommerce, SEO-плагины, кэш. По одному, с проверкой после каждого.
  5. Ядро WordPress в последнюю очередь.
  6. Проверка форм: отправить тестовую заявку и убедиться, что она дошла.

Шестой пункт пропускают чаще всего, а он самый дорогой. Сломанная форма не роняет сайт, она молча не отправляет заявки, и заметить это можно через две недели по упавшей выручке.

Автообновления только для безопасности

Полностью выключать автообновления я не советую: критические дыры в популярных плагинах закрываются постоянно, и месяц без патча это реальный риск. Разумный компромисс это автообновления для плагинов безопасности и для минорных релизов ядра, ручной режим для всего остального.

add_filter('auto_update_plugin', function ($update, $item) {
    $auto = ['wordfence', 'limit-login-attempts-reloaded', 'better-wp-security'];
    return in_array($item->slug, $auto, true);
}, 10, 2);

Код кладётся в functions.php дочерней темы или в mu-plugin. В админке то же самое настраивается вручную в списке плагинов ссылкой «Включить автообновления» напротив нужных строк.

Бэкап, который вы проверяли

Бэкап, который никто ни разу не разворачивал, это не бэкап, а надежда. Раз в квартал берите последний архив и поднимайте из него сайт на тестовом поддомене. Пятнадцать минут работы. Как собрать нормальную схему без платных плагинов, я расписывал в заметке про резервные копии WordPress.

Что писать в журнал работ

После аварии всегда кажется, что уж это вы точно запомните. Через полгода при похожей поломке вы не вспомните ни версию, ни плагин, ни что помогло. Журнал решает это одной строкой на событие.

Минимальный набор полей:

  • дата и время;
  • что обновлялось, с какой версии на какую;
  • что сломалось и на каких страницах;
  • что сделали;
  • статус: закрыто, ждём релиз вендора, обходной путь.

Выглядит это буднично и занимает секунды:

2026-09-24 11:40  ACF PRO 6.3.11 -> 6.4.0
  симптом: 500 на /uslugi/, в логе Uncaught TypeError в acf_get_field_group
  действие: откат до 6.3.11 из архива, плагин исключён из автообновлений
  статус: ждём 6.4.1, проверить после 10.10

Хранить можно где угодно: файл CHANGELOG.md в репозитории, страница в Notion, закреплённое сообщение в рабочем чате. Важно не место, а то, что запись появляется в момент работы, а не восстанавливается по памяти в конце месяца.

Второй смысл журнала денежный. Когда владелец сайта спрашивает, за что он платит абонентку, журнал отвечает на этот вопрос лучше любого отчёта. У меня в тарифах журнал работ входит в любой пакет, включая годовой за 35 000 рублей, именно поэтому: без него разговор о ценности обслуживания превращается в обмен ощущениями.

Короткий чек-лист на случай аварии

Распечатайте или сохраните в заметки, чтобы в момент паники не думать:

  1. Сделать снимок текущего состояния: архив папки wp-content и дамп базы. Даже сломанного.
  2. Отключить все плагины (переименовать папку или wp plugin deactivate --all).
  3. Убедиться, что сайт открылся. Если нет, дело не в плагинах: смотрите тему, ядро, PHP, хостинг.
  4. Включить лог WP_DEBUG_LOG, посмотреть wp-content/debug.log.
  5. Найти виновника половинным делением, проверяя не только главную.
  6. Откатить его версию, а не весь сайт.
  7. Проверить формы и оплату.
  8. Записать в журнал: версии, симптом, решение.
  9. Исключить плагин из автообновлений до выхода следующего релиза.
  10. Почистить кэш и убедиться, что посетители видят рабочую версию.

Если сайт лежит прямо сейчас и SSH у вас нет, а хостинг отвечает шаблонными письмами, напишите мне через форму на главной. Разбираю такие поломки регулярно: типовой откат занимает от получаса до двух часов вместе с диагностикой и записью в журнал. Разработку сайтов с нуля и редизайн я не веду, только приведение в порядок и обслуживание существующих.

Частые вопросы

Что делать, если после обновления сайт упал

Отключить все плагины разом через переименование папки, убедиться, что сайт поднялся, и включать по одному. Если доступа к админке нет, всё это делается по FTP.

Как откатить плагин на прошлую версию

Скачать нужную версию из каталога и залить поверх, предварительно удалив текущую папку плагина. Настройки при этом обычно сохраняются, они лежат в базе.

Как найти виновника быстрее

Делением пополам: отключить половину плагинов, проверить, потом половину оставшихся. На двадцати плагинах это пять шагов вместо двадцати.

Как не повторять эту историю

Не жать обновить всё разом на боевом сайте. Обновлять пакетами по три-пять с проверкой после каждого, держать свежий бэкап и вести журнал: что и когда обновляли.

Передайте техническую часть в надёжные руки.

Слежу за хостингом, бэкапами и обновлениями. Когда что-то пойдёт не так – звоните мне, не своему программисту, не в спортзал и не маме.

Короткие вопросы по теме

Все вопросы по теме "CMS: WordPress, Битрикс, Tilda и другие"

Заявка

Обсудим задачу

Напишите имя и телефон, выберите удобный канал. Перезвоню или напишу в течение часа в рабочее время.

Куда удобнее ответить?