Диагностика проблемы: зачем удалять неиспользуемые изображения
Со временем в медиа-библиотеке WordPress накапливается множество изображений, которые не связаны ни с одним постом или страницей. Они занимают место на сервере и могут замедлять резервное копирование и общую производительность сайта. Для сайтов с большим трафиком и объемом контента это становится критично.
Чтобы определить, есть ли на сайте такие изображения, нужно:
- Проверить размер папки
wp-content/uploads. Если она слишком велика — это первый признак. - Использовать запросы к базе данных для поиска неиспользуемых attachment post type.
- Проверить через плагины, если хотите быстро получить отчет (например, Media Cleaner), но такие плагины иногда удаляют нужные файлы, если есть кастомные связи.
Пошаговое решение: удаление неиспользуемых изображений вручную через функции
1. Создание скрипта для поиска неиспользуемых attachment
WordPress хранит изображения как посты типа attachment. Чтобы найти все изображения, не прикрепленные к постам или страницам, можно использовать следующий запрос:
$unused_attachments = $wpdb->get_results(
"SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = 0"
);Однако у многих сайтов бывают кастомные связи, и post_parent может быть 0, но изображение используется в содержимом. Поэтому нужно проверить, есть ли ID изображения в контенте других постов.
2. Проверка использования в содержимом постов
Для каждого attachment ID нужно выполнить поиск по содержимому постов и кастомных полей, чтобы убедиться, что изображение не используется.
function is_attachment_used($attachment_id) {
global $wpdb;
$attachment_url = wp_get_attachment_url($attachment_id);
// Поиск в содержимом постов
$count = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $wpdb->posts WHERE post_content LIKE %s",
'%' . $wpdb->esc_like($attachment_url) . '%'
));
// Проверка связей через post_parent
$parent_id = get_post_field('post_parent', $attachment_id);
if ($count > 0 || $parent_id > 0) {
return true;
}
return false;
}3. Удаление неиспользуемых изображений
Когда список неиспользуемых attachment готов, их можно удалить программно:
foreach ($unused_attachments as $attachment) {
if (!is_attachment_used($attachment->ID)) {
wp_delete_attachment($attachment->ID, true); // true - удаляет физический файл
}
}Рекомендуется запускать этот код через WP-CLI или временный сниппет, а не напрямую в шаблоне.
Проверка результата после внедрения
- Проверьте размер папки
wp-content/uploadsдо и после — он должен уменьшиться. - Перейдите в «Медиафайлы» — количество элементов уменьшится.
- Проверьте ключевые страницы и посты на наличие изображений — они не должны пропадать.
- Рекомендуется сделать полный бэкап перед удалением и проверить сайт после.
Частые ошибки и как исправить
- Удаление нужных файлов из-за кастомных связей. Проблема: изображения используются в метаполях или сторонних таблицах, а не в
post_contentиpost_parent. Решение: расширить проверку на кастомные поля, например, поискать в таблицеpostmeta. - Удаление файлов без бэкапа. Решение: всегда делать резервную копию сайта и базы перед массовым удалением.
- Высокая нагрузка на базу при проверке всех attachment. Решение: разбивать процесс на партии и запускать через WP-CLI.
Практические советы по безопасности и производительности
- Используйте WP-CLI для запуска скриптов удаления — это снижает риск тайм-аутов и ошибок.
- Для регулярного удаления можно настроить WP-Cron с разбивкой на партии, чтобы не перегружать сервер.
- Используйте плагины с осторожностью, например, Clearfy Pro предлагает функции для оптимизации медиа-библиотеки и удаления дублей.
Сравнение методов удаления неиспользуемых изображений
| Метод | Преимущества | Недостатки |
|---|---|---|
| Ручной код (WP-CLI или сниппеты) | Полный контроль, можно кастомизировать проверку | Требует опыта, сложность в учёте всех связей |
| Плагины (Media Cleaner, Clearfy) | Простота использования, визуальный интерфейс | Риск удаления нужных файлов, нагрузка на сайт |
| Ручное удаление через админку | Минимальный риск, простота | Занимает много времени, не подходит для больших сайтов |