© 2008-2024 г.
Все права защищены

Простая система лайков для любого сайта без подключения к базе данных на PHP+JS с определением IP посетителя

Мой блог создан на CMS Publii и из коробки нет практически ничего для блога - комментариев, счетчиков просмотра постов и лайков и это даже хорошо.

CMS Publii генерирует чистые статические файлы html в сайт из довольно удобной программы на Windows.

Я создал простую систему лайков, которая подойдет любому сайту и без подключения к базе данных, что для меня важно. Данный скрипт использую на всех своих сайтах и он хорошо себя зарекомендовал. При нажатии на кнопку лайка в списке постов или в одиночным она меняет цвет на красный, счетчик увеличивается +1 и записывается в JSON файл данные id и ip посетителя. Повторно нажать на кнопку не получится, только если сменить IP. 

Содержание статьи

Обработчик PHP

Я создал 2 файла. Один обрабатывает и подсчитывает количество лайков, а другой возвращает значения и положил их в корень сайта.

1. like.php

<?php
// Путь к файлу JSON для хранения данных о лайках
$likesFile = 'likes.json';

// Получение данных из POST запроса
$data = json_decode(file_get_contents('php://input'), true);
$postId = $data['postId'];
$ipAddress = $_SERVER['REMOTE_ADDR'];

// Загрузка данных о лайках из файла JSON
$likesData = [];
if (file_exists($likesFile)) {
    $likesData = json_decode(file_get_contents($likesFile), true);
}

// Проверка, есть ли уже лайк от этого IP-адреса
if (!isset($likesData[$postId][$ipAddress])) {
    // Увеличение счетчика лайков
    if (!isset($likesData[$postId])) {
        $likesData[$postId] = [];
    }
    $likesData[$postId][$ipAddress] = true;

    // Сохранение данных о лайках в файл JSON
    file_put_contents($likesFile, json_encode($likesData));

    // Подсчет общего количества лайков для данного поста
    $likeCount = count($likesData[$postId]);

    // Возвращение значения счетчика лайков в формате JSON
    echo json_encode(['likes' => $likeCount]);
} else {
    // Если лайк уже был поставлен этим IP-адресом, возвращаем текущее количество лайков
    $likeCount = count($likesData[$postId]);
    echo json_encode(['likes' => $likeCount]);
}
?>

2. get_likes.php

<?php
// Путь к файлу JSON для хранения данных о лайках
$likesFile = 'likes.json';

// Получение ID поста из запроса
$postId = $_GET['postId'];

// Загрузка данных о лайках из файла JSON
$likesData = [];
if (file_exists($likesFile)) {
    $likesData = json_decode(file_get_contents($likesFile), true);
}

// Подсчет общего количества лайков для данного поста
$likeCount = isset($likesData[$postId]) ? count($likesData[$postId]) : 0;

// Возвращение значения счетчика лайков в формате JSON
echo json_encode(['likes' => $likeCount]);
?>

Js код

Его нужно разместить перед закрывающимся тегом </body>

<script>
 document.addEventListener("DOMContentLoaded", function() {
    const likeButtons = document.querySelectorAll('.like-btn');
    likeButtons.forEach(button => {
        button.addEventListener('click', function() {
            const postId = this.getAttribute('data-post-id');
            likePost(postId, this);
        });
    });

    // Загрузка и отображение счетчика лайков и состояния лайка при загрузке страницы
    loadLikes();

    function likePost(postId, button) {
        // Отправка запроса на сервер
        fetch('like.php', {
            method: 'POST',
            body: JSON.stringify({ postId: postId })
        })
        .then(response => response.json())
        .then(data => {
            // Обновление отображения счетчика лайков
            const likeCountSpan = document.querySelector(`[data-post-id="${postId}"] + .like-count`);
            likeCountSpan.innerText = data.likes;

            // Добавление класса active к кнопке
            button.classList.add('active');

            // Сохранение состояния лайка в локальное хранилище
            localStorage.setItem(`like_${postId}`, 'liked');
        })
        .catch(error => console.error('Error:', error));
    }

    function loadLikes() {
        // Загрузка счетчиков лайков и состояния лайка при загрузке страницы
        likeButtons.forEach(button => {
            const postId = button.getAttribute('data-post-id');
            fetchLikes(postId, button);
        });
    }

    function fetchLikes(postId, button) {
        fetch(`get_likes.php?postId=${postId}`)
        .then(response => response.json())
        .then(data => {
            // Обновление отображения счетчика лайков
            const likeCountSpan = document.querySelector(`[data-post-id="${postId}"] + .like-count`);
            likeCountSpan.innerText = data.likes;

            // Проверка состояния лайка в локальном хранилище и добавление класса active
            if (localStorage.getItem(`like_${postId}`) === 'liked') {
                button.classList.add('active');
            }
        })
        .catch(error => console.error('Error:', error));
    }
});


</script>

Создание пустого файла likes.json

Просто создайте файл likes.json и положите в корень вашего сайта. В данный файл будут записываться данные содержащие IP пользователя, который его лайкнул и ID поста.

Пример данных, которые записываются в likes.json

{"7":{"43.163.139.18":true,"213.100.37.245":true}}
...

Чтобы ограничить доступ к данным извне в файле likes.json необходимо внести правила в файле .htaccess. Если его нет, то создать и положить в корень сайта.

<FilesMatch ".(json)$">
    deny from all
</FilesMatch>

HTML код вывода счетчика

Данный код нужно добавить, где вы хотите вывести кнопку со счетчиком лайков. Это может быть список постов, одиночный пост, рекомендуемые посты.

 <div class="likes-counter">
   <button class="like-btn" data-post-id="{{id}}">
     <svg width="20" height="18" viewBox="0 0 22 20" xmlns="http://www.w3.org/2000/svg">
       <path d="M15.1111 1C18.6333 1 21 4.3525 21 7.48C21 13.8138 11.1778 19 11 19C10.8222 19 1 13.8138 1 7.48C1 4.3525 3.36667 1 6.88889 1C8.91111 1 10.2333 2.02375 11 2.92375C11.7667 2.02375 13.0889 1 15.1111 1Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
     </svg>
   </button>
   <span class="like-count">0</span> 
</div>

Обратите внимание на атрибут data-post-id="{{id}}", в него я получаю id поста. В CMS Publii это делается просто добавив {{id}}. В вашем случае получение id поста может отличаться. Читайте документацию к вашей CMS как получить ID.

Стили CSS

.likes-counter {
	display: flex;
    align-items: center;
}
.like-btn.active svg {
	fill: red;
    stroke:red;
}
.like-btn {
	background: none;
    stroke: black;
    fill: white;
    margin-right: 5px;
    padding: 0;
    display: flex;
}
.like-btn:hover {
	background: none !important;
}
.like-count {
	line-height: 1;
    font-size: .8789062495rem;
}
.like-btn svg:hover {
	fill: red;
    stroke:red;
}
.like-btn:active, .like-btn:focus {
    background: none;
	
}

Результатом будет кнопка в виде сердца и счетчиком справа. При наведении на кнопку меняется цвет на красный, а при нажатии цвет сохраняется. Счетчик учитывает лайки как из списка постов, так и из одиночных.

Вот собственно и все. Если у вас возникают какие-либо сложности, то задавайте вопросы в комментариях.

Привет Username! Я Алексей Костюк
14 лет занимаюсь тем, что помогаю людям создавать сайты и дизайн, настраивать рекламу, продвигать проекты в Интернете. Ну и иногда еще принтер починить ;) Я создал этот блог, чтобы делить своим опытом и мыслями, а если вам нужна моя помощь, то вы знаете, где меня искать. Перейти на мой сайт

Похожие посты

Сайты
0

Как не надо делать юридический сайт. Практические советы для успешного создания сайта для юристов

Не для кого не секрет, что юридическая тематика в интернете самая конкурентная. Юристов, адвокатов, юридических компаний великое множество. Я имел опыт в создании сайтов как…

SEO
0

Накрутка поведенческих факторов в Яндексе. Как я боролся с отказами и прямыми заходами и что делать сайтам в 2024 году?

В прошлом году, ничего не предвещая беды, я любовался красивой статистикой посещений своего сайта в Яндекс Метрике. Мой сайт был в ТОПе Яндекса по тематике…