В WordPress при каждом сохранении поста автоматически создаются ревизии — версии записей, которые позволяют откатиться к предыдущим изменениям. Они очень полезны для восстановления контента, но со временем могут значительно разрастись и перегрузить базу данных, что замедляет работу сайта.
В этой статье мы разберём, как создать собственное решение для удаления старых ревизий в WordPress без использования сторонних плагинов. Это решение поможет контролировать количество ревизий и оптимизировать базу данных, избавляясь от лишнего мусора.
Что такое ревизии в WordPress и зачем их удалять
Ревизии — это автоматические или ручные сохранения версии записи. Они хранятся в таблице wp_posts с типом revision. Если у вас много записей и частые изменения, количество ревизий может достигать тысяч, что увеличивает размер базы и замедляет запросы.
Удаление старых ревизий поможет:
- Снизить размер базы данных
- Ускорить запросы в админке и на фронтенде
- Уменьшить нагрузку на сервер при резервном копировании и миграциях
Почему не всегда стоит отключать ревизии полностью
Некоторые советуют отключить ревизии полностью с помощью константы WP_POST_REVISIONS, установив её в 0 или false. Однако ревизии — это важный инструмент для восстановления контента после случайных ошибок. Лучше ограничить число ревизий, а не удалять их полностью.
Например, в wp-config.php можно добавить:
define('WP_POST_REVISIONS', 5);Так будет храниться только 5 последних версий записи, остальные будут удаляться автоматически при сохранении новых.
Создание пользовательского скрипта для удаления старых ревизий
Если у вас накопилось уже много ревизий, можно написать собственный PHP-скрипт для их удаления. Такой скрипт удобно запускать раз в неделю или месяц через WP-Cron или вручную.
Пример функции wp-lessons-delete-old-revisions(), которая удаляет все ревизии, кроме последних 3 для каждой записи:
function wp_lessons_delete_old_revisions() {
global $wpdb;
// Получаем ID постов с ревизиями
$post_ids = $wpdb->get_col("SELECT DISTINCT post_parent FROM {$wpdb->posts} WHERE post_type = 'revision'");
foreach ($post_ids as $post_id) {
// Получаем ревизии кроме последних 3
$old_revisions = $wpdb->get_col($wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = %d ORDER BY post_date DESC LIMIT 18446744073709551615 OFFSET 3",
$post_id
));
if ($old_revisions) {
foreach ($old_revisions as $revision_id) {
wp_delete_post($revision_id, true);
}
}
}
// Оптимизируем таблицу после удаления
$wpdb->query("OPTIMIZE TABLE {$wpdb->posts}");
}
// Запуск функции вручную
// wp_lessons_delete_old_revisions();Этот код удалит все ревизии, кроме трёх последних для каждого поста, и оптимизирует таблицу wp_posts. Рекомендуется запускать такую функцию в моменты низкой нагрузки на сайт.
Как запустить функцию через WP-Cron
Чтобы автоматизировать процесс, добавим событие в планировщик WP-Cron:
function wp_lessons_schedule_revision_cleanup() {
if (!wp_next_scheduled('wp_lessons_revision_cleanup_event')) {
wp_schedule_event(time(), 'weekly', 'wp_lessons_revision_cleanup_event');
}
}
add_action('wp', 'wp_lessons_schedule_revision_cleanup');
add_action('wp_lessons_revision_cleanup_event', 'wp_lessons_delete_old_revisions');Этот код создаст еженедельное событие, которое будет запускать нашу функцию очистки ревизий.
Альтернативы скрипту: плагины для управления ревизиями
Если вы предпочитаете готовые решения, можно использовать плагины с похожим функционалом. Они позволяют ограничивать количество ревизий и удалять старые:
- WP-Optimize — плагин для очистки базы и удаления ревизий.
- Revision Control — ограничивает количество ревизий по типам записей.
Для интеграции с WPShop можно рассмотреть Clearfy Pro, который оптимизирует работу сайта, включая управление ревизиями.
Как избежать проблем с удалением ревизий
При работе с ревизиями важно учитывать несколько моментов:
- Всегда делайте резервную копию базы перед массовым удалением данных.
- Не удаляйте ревизии, если на сайте активно ведётся редактирование и возможен откат.
- После удаления и оптимизации таблиц проверьте работоспособность сайта и админки.
Если вы используете кэширование, очистите кэш после удаления ревизий, чтобы избежать конфликтов.
Пример функции для безопасного удаления ревизий с логированием
function wp_lessons_delete_old_revisions_safe() {
global $wpdb;
$log = [];
$post_ids = $wpdb->get_col("SELECT DISTINCT post_parent FROM {$wpdb->posts} WHERE post_type = 'revision'");
foreach ($post_ids as $post_id) {
$old_revisions = $wpdb->get_col($wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = %d ORDER BY post_date DESC LIMIT 18446744073709551615 OFFSET 3",
$post_id
));
foreach ($old_revisions as $revision_id) {
if (wp_delete_post($revision_id, true)) {
$log[] = "Удалена ревизия ID: $revision_id для записи ID: $post_id";
} else {
$log[] = "Ошибка при удалении ревизии ID: $revision_id";
}
}
}
$wpdb->query("OPTIMIZE TABLE {$wpdb->posts}");
if ($log) {
error_log(implode("\n", $log));
}
}
Такой подход помогает отслеживать результаты работы скрипта и быстро выявлять возможные ошибки.