Как правильно добавлять данные о кол-ве просмотров постов в базе данных WordPress?
Приветствую!
Для практики хотел разработать простенький плагин для WordPress, одной из функций которого было бы отображение количества просмотров для каждого поста. Но не знаю как правильно реализовать в плане обновления данных счетчика в базе.
Хотел узнать, каким образом правильно обновлять количество просмотров в БД. Корректно ли это делать при каждом просмотре поста? Или данные где-то сохраняются и в базу добавляются потом, а не так часто?
Плох ли такой способ?
function increment_post_views() { if (is_singular()) { $post_id = get_the_ID(); $views_key = 'post_views_count'; $views = get_post_meta($post_id, $views_key, true); $views = $views ? intval($views) + 1 : 1; update_post_meta($post_id, $views_key, $views); } } add_action('wp', 'increment_post_views'); function display_post_views() { if (is_singular()) { $post_id = get_the_ID(); $views_key = 'post_views_count'; $views = get_post_meta($post_id, $views_key, true); echo 'Количество просмотров: ' . $views; } } |
function increment_post_views() { if (is_singular()) { $post_id = get_the_ID(); $views_key = 'post_views_count'; $views = get_post_meta($post_id, $views_key, true); $views = $views ? intval($views) + 1 : 1; update_post_meta($post_id, $views_key, $views); } } add_action('wp', 'increment_post_views'); function display_post_views() { if (is_singular()) { $post_id = get_the_ID(); $views_key = 'post_views_count'; $views = get_post_meta($post_id, $views_key, true); echo 'Количество просмотров: ' . $views; } }
Или тут зависит от посещаемости? Чем больше она, тем больше проблем от этого способа будет?
Благодарю за помощь!
Дополнительные вопросы
Михаил Р. @Mike_Ro Python, JS, WordPress, SEO, Bots, Adversting
Корректно ли это делать при каждом просмотре поста?
Или тут зависит от посещаемости? Чем больше она, тем больше проблем от этого способа будет?
Все верно, нагрузка на сервер/бд будет прямо пропорциональна посещаемости.
Хотел узнать, каким образом правильно обновлять количество просмотров в БД.
Или данные где-то сохраняются и в базу добавляются потом, а не так часто?
Все верно, но зависит от нагрузки:
- Малая нагрузка: делаем стандартным образом, при обновление поста - обновляем счетчик в бд.
- Средняя нагрузка: обновляем код так, чтобы он мог использовать транзитное кэширование wp (set_transient()).
- Большая нагрузка: используем внешние очереди (например redis или rabbitmq), данные с которых снимаем и пишем в бд раз в N сек/мин.
Ответы:
В вашем способе будут теряться просмотры из-за состояния гонки, а в целом он годится при небольших нагрузках
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Увеличивать счётчик просмотров в базе при каждом открытии страницы можно, но это не лучший вариант для нагруженного сайта. Каждый просмотр превращается в SQL-запись, сбрасывает кэш объекта/страницы и создаёт лишнюю нагрузку. Для учебного плагина это нормально, для продакшена лучше делать буферизацию.
Плохой вариант:
update_post_meta($post_id, 'views', (int) get_post_meta($post_id, 'views', true) + 1);
Проблемы: гонки при одновременных запросах, постоянные записи в БД, нет защиты от ботов и обновлений страницы.
Лучше использовать атомарный SQL:
global $wpdb; $post_id = get_the_ID(); $wpdb->query( $wpdb->prepare( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) VALUES (%d, 'views', 1) ON DUPLICATE KEY UPDATE meta_value = meta_value + 1", $post_id ) );
Но для этого нужен уникальный индекс на
post_id + meta_key, которого в стандартнойwp_postmetaнет. Поэтому многие делают отдельную таблицу:CREATE TABLE wp_post_views ( post_id BIGINT UNSIGNED NOT NULL PRIMARY KEY, views BIGINT UNSIGNED NOT NULL DEFAULT 0 );
И обновляют её:
$wpdb->query($wpdb->prepare( "INSERT INTO wp_post_views (post_id, views) VALUES (%d, 1) ON DUPLICATE KEY UPDATE views = views + 1", $post_id ));
Для хорошей схемы можно писать просмотры в Redis/файл/очередь и раз в несколько минут сбрасывать агрегаты в БД. Также стоит не считать админов, ботов, быстрые повторы одного IP/session и preview.
Итог: для практики можно начать с post meta, но правильнее для счётчика просмотров сделать отдельную таблицу и, при необходимости, буферизацию.