Счётчик просмотров на сайте без БД на PHP, JS
Не так давно я писал пост как создать лайки для блога без подключения к БД и теперь решил рассказать как создать счётчик просмотров страниц на PHP и JS. Статья рассчитана на людей, которые имеют представление об основах PHP и JS и навыки подключения файлов.
Содержание статьи
Обработчик PHP
Мы должны создать два файла, который один будет считать просмотры по схеме 1 IP = 1 просмотр и записывать данные в файл view.json.
Файл update_views.php
<?php
header('Content-Type: application/json');
$file = 'view.json';
$data = json_decode(file_get_contents($file), true);
$postId = $_POST['postId'];
$userIp = $_SERVER['REMOTE_ADDR'];
if (!isset($data[$postId])) {
$data[$postId] = ['views' => 0, 'ips' => []];
}
if (!in_array($userIp, $data[$postId]['ips'])) {
$data[$postId]['views']++;
$data[$postId]['ips'][] = $userIp;
file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT));
}
echo json_encode(['views' => $data[$postId]['views']]);
?>
Как вы видите мы создаем файл view.json в который записываем данные: ip посетителя, id страницы и количество просмотров.
Файл get_views.php
<?php
header('Content-Type: application/json');
$file = 'view.json';
$data = json_decode(file_get_contents($file), true);
$postId = $_GET['postId'];
if (isset($data[$postId])) {
echo json_encode(['views' => $data[$postId]['views']]);
} else {
echo json_encode(['views' => 0]);
}
?>
Этот файл нужен, чтобы получить данные из файла view.json и передать просмотры каждой страницы в счетчик
JS обработка счетчика
Первый скрипт обрабатывает данные при открытии страницы, а у меня это статья на этом блоге.
document.addEventListener('DOMContentLoaded', function() {
const pageviewElement = document.querySelector('.post .pageview-count');
if (pageviewElement) {
const postId = pageviewElement.getAttribute('data-id');
fetch('/update_views.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `postId=${postId}`
})
.then(response => response.json())
.then(data => {
pageviewElement.textContent = data.views;
})
.catch(error => {
console.error('Error:', error);
});
}
});
В этой строке вам нужно прописать нужные селекторы до счетчика
const pageviewElement = document.querySelector('.post .pageview-count');
У меня HTML структура блоговой страницы следующая:
<main class="post">
<article class="content">
...
<!-- Счетчик просмотров -->
<span class="pageview-count" data-id="{{id}}">0</span>
</acrticle>
</main>
Поэтому в подключении JS я указал .post .pageview-count
, который находит класс post и далее сам счетчик внутри статьи.
Строка fetch('/update_views.php', {
создает асинхронный POST запрос к PHP обработчику, который лежит у меня в корне сайта. Вы можете указать свой путь до файла update_views.php
Сам скрипт вы можете подключить на странице вашего сайта, либо в <head></head>, а если это Wordpress, то это файлы page.php, post.php.
Второй скрипт JS обновляет счетчик просмотров на общих страницах, где содержатся записи статей, тегов и т.д.
document.addEventListener('DOMContentLoaded', function() {
const pageviewElements = document.querySelectorAll('.pageview-count');
function updateViewCount(element, postId) {
fetch(`/get_views.php?postId=${postId}`)
.then(response => response.json())
.then(data => {
element.textContent = data.views;
})
.catch(error => {
console.error('Error:', error);
});
}
pageviewElements.forEach(element => {
const postId = element.getAttribute('data-id');
updateViewCount(element, postId);
});
// Обновляем счетчики каждые 10 секунд
setInterval(() => {
pageviewElements.forEach(element => {
const postId = element.getAttribute('data-id');
updateViewCount(element, postId);
});
}, 10000);
});
Строка fetch(`/get_views.php?postId=${postId}`)
создает асинхронный GET запрос к PHP обработчику get_views.php, который лежит у меня в корне сайта и получает данные о количестве просмотров каждой страницы. Вы можете указать свой путь до файла. Также счетчик обновляется каждые 10 секунд. Этот параметр вы можете отрегулировать сами.
HTML подключение счётчика
У меня на сайте, где работает данный счётчик подключено такой строкой:
<span class="pageview-count" data-id="{{id}}">0</span>
Что такое data-id? Это атрибут, который получает из переменной {{id}}
id страницы. В вашем проекте получение id страницы может быть реализовано по другому, а если у вас CMS, то смотрите документацию по получению id. Данным кодом можно выводить счетчик на нужных страницах и в списке блога.
Пример получения id записи блога в CMS Wordpress
Внутри записи (single.php)
<?php
get_header();
if (have_posts()) :
while (have_posts()) : the_post();
$post_id = get_the_ID();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<h1 class="entry-title"><?php the_title(); ?></h1>
</header>
<div class="entry-content">
<?php the_content(); ?>
<span class="pageview-count" data-id="<?php echo $post_id; ?>">0</span>
</div>
</article>
<?php
endwhile;
endif;
get_footer();
?>
В списке записей (index.php или archive.php)
<?php
get_header();
if (have_posts()) :
while (have_posts()) : the_post();
$post_id = get_the_ID();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
</header>
<div class="entry-content">
<?php the_excerpt(); ?>
<span class="pageview-count" data-id="<?php echo $post_id; ?>">0</span>
</div>
</article>
<?php
endwhile;
endif;
get_footer();
?>
Файл view.json
Достаточно создать пустой файл и положить в корень сайта, либо в другую директорию по вашему желанию и разрешить запись в него cmod 777
. Доступ к данному файлу нужно ограничить, чтобы никто не смог посмотреть записанные данные. Делается это путем внесения кода в файле .htaccess:
<Files view.json>
order allow,deny
deny from all
</Files>
Теперь при переходе site.ru/view.json будет отдаваться 403 ошибка.
Оформление счетчика как у меня в блоге
HTML:
<div class="view-counter">
<svg width="22" height="16" viewBox="0 0 22 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.42012 8.71318C1.28394 8.49754 1.21584 8.38972 1.17772 8.22342C1.14909 8.0985 1.14909 7.9015 1.17772 7.77658C1.21584 7.61028 1.28394 7.50246 1.42012 7.28682C2.54553 5.50484 5.8954 1 11.0004 1C16.1054 1 19.4553 5.50484 20.5807 7.28682C20.7169 7.50246 20.785 7.61028 20.8231 7.77658C20.8517 7.9015 20.8517 8.0985 20.8231 8.22342C20.785 8.38972 20.7169 8.49754 20.5807 8.71318C19.4553 10.4952 16.1054 15 11.0004 15C5.8954 15 2.54553 10.4952 1.42012 8.71318Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.0004 11C12.6573 11 14.0004 9.65685 14.0004 8C14.0004 6.34315 12.6573 5 11.0004 5C9.34355 5 8.0004 6.34315 8.0004 8C8.0004 9.65685 9.34355 11 11.0004 11Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span class="pageview-count" data-id="{{id}}">0</span>
</div>
CSS:
.view-counter {
display: flex;
align-items: center;
}
.view-counter svg {
margin-right: 5px;
}
Готовые файлы для скачивания
Для удобства я подготовил архив со всеми файлам, достаточно скачать и настроить по моей инструкции, а если есть вопросы пишите в комментариях.