В этой статье я приведу пример создания лайков и дизлайков для новостей. Голосование будет работать без перезагрузки страницы, за счет использования технологии передачи данных на сервер — 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 лайков закончено. Скрипт и дамп базы данных вы можете скачать в архиве вот тут.

(86 оценок, среднее: 4,03 из 5)
Очень интересное решение, спасибо Вам большое. Подскажите пожалуйста, как можна использовать данный скрипт, если на странице не один элемент Like/Dislike т.е. на странице список где в каждой строчке стоит элемент Like/Dislike? Пробовал так <span id="like-«>like () потом в ajax_test.php explode’ром получаю тип, но … не работает почему-то. Помогите пожалуйста.
Здравствуйте! Вы можете в функцию setVote, добавить третий параметр — уникальный идентификатор элемента, за который пользователи будут голосовать. Получив в функции этот id, передавайте его аяксом на сервер и там уже по нему делайте запись в базу данных.
Добрый день. А гугл хавает такую конструкцию в виде сниппета в выдаче?
Здравствуйте, вы о чем, я вас не понял? :)
Хммм. Например, если ввести в ПС гугл запрос «Добавляем рейтинг для google», появится выдача, в которой есть сайты, у которых в сниппете есть звёзды. Вот я испросил, будет ли у Вашего примера вывод в гугле такой же.
Нет, так рейтинг не индектируется
Здравствуйте! Подскажите, пожалуйста, как отвязать скрипт от id пользователя. Запретить только, ставить лайки, например один раз в сутки.