Диагностика проблемы: почему устаревшие внутренние ссылки вредят сайту
Внутренние ссылки, ведущие на удалённые или изменённые страницы, ухудшают SEO и пользовательский опыт. Такие ссылки вызывают 404 ошибки, снижают рейтинг страниц и увеличивают показатель отказов. Особенно остро проблема стоит на крупных сайтах с сотнями и тысячами записей, где ручная проверка невозможна.
Как выявить устаревшие внутренние ссылки?
- Используйте плагин Broken Link Checker или аналогичные инструменты для обнаружения битых ссылок;
- Выполните SQL-запросы в базе данных для поиска ссылок на несуществующие записи;
- Проверьте логи сервера на 404 ошибки с внутренними URL.
Пошаговое решение: автоматизация удаления устаревших ссылок через код
Для автоматического удаления внутренних ссылок на удалённые записи рассмотрим пример кода, который сканирует контент записей и удаляет ссылки на несуществующие записи.
Основная идея — через хук save_post при обновлении записи проверять все ссылки в содержимом и убирать ссылку, если страница удалена.
function wplinks_remove_broken_internal_links($post_id) {
if (wp_is_post_revision($post_id)) {
return;
}
$post = get_post($post_id);
if (!$post || $post->post_status != 'publish') {
return;
}
$content = $post->post_content;
// Регулярное выражение для поиска всех ссылок
preg_match_all('/<a\s+(?:[^>]*?\s+)?href=["\']([^"\']*)["\']/i', $content, $matches);
$links = $matches[1];
foreach ($links as $link) {
// Проверяем внутренние ссылки на сайт
if (strpos($link, site_url()) === 0) {
$path = str_replace(site_url(), '', $link);
$url_parts = parse_url($path);
$slug = isset($url_parts['path']) ? trim($url_parts['path'], '/') : '';
if (!$slug) {
continue;
}
// Ищем запись по слагу
$linked_post = get_page_by_path($slug, OBJECT, array('post', 'page', 'product'));
if (!$linked_post) {
// Удаляем ссылку, оставляем текст
$pattern = '/<a[^>]*href=["\']' . preg_quote($link, '/') . '["\'][^>]*>(.*?)<\/a>/i';
$content = preg_replace($pattern, '$1', $content);
}
}
}
// Обновляем запись с очищенным контентом
remove_action('save_post', 'wplinks_remove_broken_internal_links');
wp_update_post(array(
'ID' => $post_id,
'post_content' => $content,
));
add_action('save_post', 'wplinks_remove_broken_internal_links');
}
add_action('save_post', 'wplinks_remove_broken_internal_links');Объяснение кода
- Функция срабатывает при сохранении записи;
- Парсит контент на наличие ссылок;
- Проверяет, существует ли объект с указанным слагом;
- Если страница удалена — удаляет ссылку, оставляя текст;
- Обновляет запись с исправленным содержимым.
Проверка результата после внедрения
Чтобы убедиться, что решение работает:
- Создайте тестовую запись с внутренними ссылками на существующие и несуществующие страницы;
- Сохраните запись — ссылки на несуществующие записи должны автоматом превратиться в обычный текст без ссылки;
- Используйте инструмент «Просмотр кода страницы» в браузере, чтобы подтвердить отсутствие битых ссылок;
- Проверьте, что при обновлении других записей подобная очистка также происходит.
Частые ошибки и как их исправить
- Удаление всех ссылок без проверки: проверьте правильность регулярных выражений, чтобы не сломать ссылки на внешние сайты.
- Циклы обновления записи: чтобы избежать бесконечного цикла из-за
wp_update_post, временно отключайте хук внутри функции. - Некорректный поиск по слагу: убедитесь, что используете правильный тип постов в
get_page_by_path, включая кастомные типы, например,productдля WooCommerce. - Проблемы с URL, содержащими параметры: для сложных URL можно дополнительно парсить параметры и исключать их из проверки.
Практические советы по безопасности и производительности
- Не запускайте проверку ссылок на всех записях одновременно — это нагрузит базу данных; используйте проверку при сохранении или по cron с ограничением партии записей.
- Кэшируйте результаты проверки ссылок, чтобы не повторять её при каждом сохранении.
- Для сайтов с WooCommerce добавляйте поддержку типов
productи их таксономий. - Регулярно делайте резервные копии базы перед массовыми правками.
Альтернативы: плагин или код? Сравнительная таблица
| Критерий | Плагин (Broken Link Checker) | Код (описанный выше) |
|---|---|---|
| Настройка | Простой, интерфейс | Требует навыков PHP |
| Нагрузка на сервер | Высокая при сканировании | Минимальна, срабатывает при сохранении |
| Гибкость | Ограничена функционалом плагина | Можно адаптировать под задачи |
| Автоматизация | Автоматическое сканирование | Автоматическая очистка при сохранении |
| Совместимость с кастомными типами | Не всегда корректно | Можно расширять вручную |