В этой статье я приведу пример создания лайков и дизлайков для новостей. Голосование будет работать без перезагрузки страницы, за счет использования технологии передачи данных на сервер — ajax. Для работы примера необходимо подключить библиотеку jQuery. Начнем.
Для начала создадим таблицы в базе данных. Их будет три. Одна для хранения тестовых новостей, вторая для тестовых пользователей и третья для связи пользователей с голосами.
С таблицами для новостей и пользователь все ясно, тут нет смысла что-то описывать. Интерес представляет третья таблица, для хранения связи пользователя и голоса, назовем таблицу votes_news2user. Записывать в эту таблицу будем id пользователи и id новости, за которую пользователь голосовал. И при каждом голосе будем проверять по таблице votes_news2user голосовал пользователь раньше или нет.
Для создания всех нужных таблиц с тестовыми данными можете воспользоваться вот этим патчем:
-- Создание таблицы с новостями CREATE TABLE IF NOT EXISTS `news` ( `id` int(10) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `small_text` varchar(255) NOT NULL, `big_text` text NOT NULL, `date_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `is_active` tinyint(1) NOT NULL, `count_like` int(10) NOT NULL, `count_dislike` int(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -- Заполнение таблицы с новостями INSERT INTO `news` (`id`, `title`, `small_text`, `big_text`, `date_create`, `is_active`, `count_like`, `count_dislike`) VALUES (1, 'Новость 1', 'короткое описание 1', 'полный текст', '2014-01-18 17:36:02', 1, 0, 0), (2, 'Новость 2', 'короткое описание 2', 'полный текст', '2014-01-18 17:36:02', 1, 0, 0), (3, 'Новость 3', 'короткое описание 3', 'полный текст', '2014-01-18 17:36:25', 1, 0, 0), (4, 'Новость 4', 'короткое описание 4', 'полный текст', '2014-01-22 20:59:53', 1, 0, 0), (5, 'Новость 5', 'короткое описание 5', 'полный текст', '2014-01-22 20:59:52', 1, 0, 0); -- Создание таблицы для пользователей CREATE TABLE IF NOT EXISTS `users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `login` varchar(50) NOT NULL, `pass` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -- Заполнение таблицы с пользователями INSERT INTO `users` (`id`, `login`, `pass`) VALUES (1, 'test', 'pass'); -- Создание таблицы для связи пользователя и голоса за новость CREATE TABLE IF NOT EXISTS `votes_news2user` ( `id` int(10) NOT NULL AUTO_INCREMENT, `id_user` int(10) NOT NULL, `id_news` int(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
После того как база данных создана и заполнена, необходимо создать страницу для вывода новостей и с кнопками для голосования:
<style> .one_news span { border: 1px dotted; cursor: pointer; display: block; margin-bottom: 5px; text-align: center; width: 85px; } .one_news span:hover{ border: 1px solid; } </style> <?php // подключение к бд include "db_connection.php"; $userId = 1; // id пользователя // достаем все новости $sql = mysql_query(" SELECT * FROM `news` ") or die(mysql_error()); $news = array(); while($r = mysql_fetch_array($sql, MYSQL_ASSOC)){ $news[] = $r; } ?> <div> <input type="hidden" id="id_user" value="<?=$userId;?>" /> <?php foreach($news as $oneNews){ ?> <div class="one_news"> <h3><?=$oneNews['title'];?></h3> <p><?=$oneNews['title'];?></p> <span id="like">Like (<b><?=$oneNews['count_like'];?></b>)</span> <span id="dislike">DisLike (<b><?=$oneNews['count_dislike'];?></b>)</span> <input type="hidden" id="id_news" value="<?=$oneNews['id'];?>" /> </div> <hr/> <?php } ?> </div>
Код скрипта для подключения к базе данных храниться в файле db_connection.php. Вот его код:
define("HOST", "localhost"); define("USER", "root"); define("PASSWORD", ""); define("DB_NAME", "test_db"); $db_connect = mysql_connect(HOST, USER, PASSWORD, TRUE); mysql_selectdb(DB_NAME,$db_connect); mysql_set_charset('utf8');
Теперь составим скрипт, который будет обрабатывать аякс запросы и если нужно, то делать записи в базу данных или выводить сообщения об ошибках. Назовем его ajax_test.php:
// подключение к бд include "db_connection.php"; // контейнер для ошибок $error = false; // получение данных $userId = (int) $_POST['id_user']; $newsId = (int) $_POST['id_news']; $type = $_POST['type']; // проверяем, голосовал ранее пользователь за эту новость или нет $sql = mysql_query(" SELECT count(*) FROM `votes_news2user` WHERE `id_user` = $userId AND `id_news` = $newsId ") or die(mysql_error()); $result = mysql_fetch_row($sql); // если что-то пришло из запроса, значит уже голосовал //var_dump($result);exit; if($result[0] > 0){ $error = 'Вы уже голосовали'; }else{ // если пользователь не голосовал, проголосуем // получем поле для голосования - лайк или дизлайк if($type == 'like') $fieldName = 'count_like'; if($type == 'dislike') $fieldName = 'count_dislike'; // делаем запись о том, что пользователь проголосовал mysql_query(" INSERT INTO `votes_news2user` (`id_user`, `id_news`) VALUES ($userId, $newsId) ") or die(mysql_error()); // делаем запись для новости - увеличиваем количесво голосов(лайк или дизлайк) mysql_query(" UPDATE `test_db`.`news` SET `$fieldName`= `$fieldName` + 1 WHERE `id` = $newsId ") or die(mysql_error()); } // делаем ответ для клиента if($error){ // если есть ошибки то отправляем ошибку и ее текст echo json_encode(array('result' => 'error', 'msg' => $error)); }else{ // если нет ошибок сообщаем об успехе echo json_encode(array('result' => 'success')); }
Остается только написать javascript, который будет отправлять ajax запросы к скрипту ajax_test.php
$(document).ready(function() { $('span#like').click(function(){ setVote('like', $(this)); }); $('span#dislike').click(function(){ setVote('dislike', $(this)); }); }); // type - тип голоса. Лайк или дизлайк // element - кнопка, по которой кликнули function setVote(type, element){ // получение данных из полей var id_user = $('#id_user').val(); var id_news = element.parent().find('#id_news').val(); $.ajax({ // метод отправки type: "POST", // путь до скрипта-обработчика url: "/ajax_test.php", // какие данные будут переданы data: { 'id_user': id_user, 'id_news': id_news, 'type': type }, // тип передачи данных dataType: "json", // действие, при ответе с сервера success: function(data){ // в случае, когда пришло success. Отработало без ошибок if(data.result == 'success'){ // Выводим сообщение alert('Голос засчитан'); // увеличим визуальный счетчик var count = parseInt(element.find('b').html()); element.find('b').html(count+1); }else{ // вывод сообщения об ошибке alert(data.msg); } } }); }
Вот и все, на этом создание ajax лайков закончено. Скрипт и дамп базы данных вы можете скачать в архиве вот тут.
Очень интересное решение, спасибо Вам большое. Подскажите пожалуйста, как можна использовать данный скрипт, если на странице не один элемент Like/Dislike т.е. на странице список где в каждой строчке стоит элемент Like/Dislike? Пробовал так <span id="like-«>like () потом в ajax_test.php explode’ром получаю тип, но … не работает почему-то. Помогите пожалуйста.
Здравствуйте! Вы можете в функцию setVote, добавить третий параметр — уникальный идентификатор элемента, за который пользователи будут голосовать. Получив в функции этот id, передавайте его аяксом на сервер и там уже по нему делайте запись в базу данных.
Добрый день. А гугл хавает такую конструкцию в виде сниппета в выдаче?
Здравствуйте, вы о чем, я вас не понял? :)
Хммм. Например, если ввести в ПС гугл запрос «Добавляем рейтинг для google», появится выдача, в которой есть сайты, у которых в сниппете есть звёзды. Вот я испросил, будет ли у Вашего примера вывод в гугле такой же.
Нет, так рейтинг не индектируется
Здравствуйте! Подскажите, пожалуйста, как отвязать скрипт от id пользователя. Запретить только, ставить лайки, например один раз в сутки.