Обновления WordPress, плагинов и тем важны для безопасности и функциональности сайта. Но иногда после обновления возникают ошибки, которые делают сайт недоступным или нарушают его работу. В таких случаях быстро вернуть предыдущую версию — задача критическая. В этой статье расскажу, как реализовать автоматический откат (rollback) обновлений WordPress при возникновении ошибок, чтобы минимизировать простой сайта.
Почему нужен автоматический откат обновлений WordPress
Обновления — это всегда риск. Даже проверенные обновления могут конфликтовать с другими плагинами или темами, привести к фатальным ошибкам PHP или ошибкам базы данных. Если не отследить проблему вовремя, сайт может быть недоступен часами или сутками.
Ручной откат — это долго и требует навыков. Автоматизация процесса позволяет:
- Сократить время простоя сайта.
- Снизить нагрузку на техническую поддержку.
- Обеспечить безопасность пользователей и контента.
Автоматический rollback пригодится и для сайтов с большим трафиком, где сбои недопустимы.
Как определить, что обновление вызвало ошибку — ключевые признаки
Автоматизация невозможна без мониторинга. Нужно понять, когда именно обновление стало причиной сбоя. Вот основные признаки, которые можно отследить программно:
- HTTP-ошибки — 500 Internal Server Error, 503 Service Unavailable.
- Фатальные PHP ошибки — сайт перестаёт загружаться, появляется белый экран.
- Ошибки в JS, нарушающие работу интерфейса.
- Ошибка подключения к базе данных после обновления.
- Проблемы с загрузкой CSS и шаблонов.
Для автоматизации лучше всего использовать мониторинг HTTP-кодов и проверку наличия fatal ошибок в логах.
Пример простой реализации автоматического отката обновлений WordPress
Идея: перед обновлением сохраняем текущую версию файлов и базы данных, запускаем обновление, проверяем работоспособность сайта, если ошибка — восстанавливаем из резервной копии.
1. Создание резервной копии перед обновлением
Для простоты сделаем бэкап только файлов плагина или темы, которую обновляем, и базы данных. Для базы данных используем встроенную функцию wp_export_db_wpexamples (пример ниже). Для файлов — копируем папку плагина.
function wpexamples_backup_plugin_files($plugin_slug) {
$plugin_dir = WP_PLUGIN_DIR . '/' . $plugin_slug;
$backup_dir = WP_CONTENT_DIR . '/backup_plugins/' . $plugin_slug . '_' . time();
if (!file_exists($backup_dir)) {
mkdir($backup_dir, 0755, true);
}
// Рекурсивное копирование
wpexamples_recursive_copy($plugin_dir, $backup_dir);
}
function wpexamples_recursive_copy($src, $dst) {
$dir = opendir($src);
@mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
wpexamples_recursive_copy($src . '/' . $file,$dst . '/' . $file);
} else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
function wp_export_db_wpexamples() {
global $wpdb;
$tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
$sql_dump = '';
foreach($tables as $table){
$table_name = $table[0];
$create_table = $wpdb->get_row("SHOW CREATE TABLE $table_name", ARRAY_N);
$sql_dump .= "\nDROP TABLE IF EXISTS `$table_name`;\n";
$sql_dump .= $create_table[1] . ";\n\n";
$rows = $wpdb->get_results("SELECT * FROM $table_name", ARRAY_A);
foreach($rows as $row){
$vals = array_map(array($wpdb, 'escape'), array_values($row));
$vals = array_map(function($val){ return "'" . addslashes($val) . "'"; }, $vals);
$sql_dump .= "INSERT INTO `$table_name` VALUES(" . implode(",", $vals) . ");\n";
}
}
$backup_file = WP_CONTENT_DIR . '/backup_db/db_backup_' . time() . '.sql';
file_put_contents($backup_file, $sql_dump);
return $backup_file;
}
2. Проверка работоспособности сайта после обновления
После обновления плагина или темы можно проверить HTTP-ответ главной страницы через функцию curl. Если код ответа не 200, значит, есть проблема.
function wpexamples_check_site_health() {
$url = get_site_url();
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($http_code === 200);
}
3. Восстановление из резервной копии при ошибке
Если проверка не прошла, возвращаем файлы и базу данных из резервной копии.
function wpexamples_restore_plugin_files($backup_dir, $plugin_slug) {
$plugin_dir = WP_PLUGIN_DIR . '/' . $plugin_slug;
wpexamples_recursive_copy($backup_dir, $plugin_dir);
}
function wpexamples_import_db_wpexamples($backup_file) {
global $wpdb;
$sql = file_get_contents($backup_file);
// Разбиваем на отдельные запросы и выполняем
$queries = explode(";\n", $sql);
foreach($queries as $query){
$trimmed = trim($query);
if(!empty($trimmed)) {
$wpdb->query($trimmed);
}
}
}
Подключение к процессу обновления
Чтобы реализовать автоматический откат, нужно интегрироваться в процесс обновления WordPress. Можно использовать хук upgrader_process_complete, который вызывается после обновления плагина или темы.
add_action('upgrader_process_complete', 'wpexamples_handle_update', 10, 2);
function wpexamples_handle_update($upgrader_object, $options) {
// Проверяем, что обновился плагин или тема
if ($options['action'] == 'update' && ($options['type'] == 'plugin' || $options['type'] == 'theme')) {
$item = reset($options['plugins'] ?? $options['themes']);
$slug = basename($item, '.php');
// 1. Делаем резервную копию
wpexamples_backup_plugin_files($slug);
$backup_db_file = wp_export_db_wpexamples();
// 2. Проверяем работоспособность
if (!wpexamples_check_site_health()) {
// 3. Откатываем изменения
$backup_dir = WP_CONTENT_DIR . '/backup_plugins/' . $slug . '_latest';
wpexamples_restore_plugin_files($backup_dir, $slug);
wpexamples_import_db_wpexamples($backup_db_file);
// Логируем
error_log('WPExamples: откат обновления плагина ' . $slug . ' из-за ошибки после обновления');
}
}
}
Рекомендации и дополнительные инструменты
Реализация автоматического отката — это сложная задача, которая требует тестирования и доработки под конкретный сайт.
- Резервное копирование базы данных лучше делать с помощью специализированных плагинов типа Clearfy Pro или WPRemark.
- Для мониторинга состояния сайта можно использовать внешние сервисы или плагины, интегрированные с логированием.
- Для больших проектов стоит рассмотреть создание staging-среды, где обновления тестируются перед переносом на продакшен.
- Также можно расширить функционал, чтобы rollback запускался не только после обновления, но и при обнаружении ошибок в течение заданного времени.
Заключение
Автоматический откат обновлений WordPress — мощный инструмент, который помогает избежать простоев и потери клиентов. В статье приведён базовый пример, который можно адаптировать и расширять под задачи вашего сайта. Важно тщательно тестировать такие решения, чтобы не усугубить проблему.