Отправка сообщения






Образец скрипта голосования (Like / Unlike) в связке AJAX/PHP/MySQL.

like-and-unlikeКак показывает практика, использование различных технологий в связке может дать неплохой результат, и в нашем случае этот факт не стал исключением. Сделаем скрипт голосования («За» / «Против») без перезагрузки страницы. Для реализации нам потребуется библиотека JQuery.

Для хранения наших данных используется MySQL, поэтому предварительно создаем таблицы в нашей базе:
1. Таблица posts – содержит данные постов. Необходимые поля в таблице id, like, unlike, name.
id – уникальный ключ поста;
like – сумма голосов «за»;
unlike – сумма голосов «против»;
name — имя поста;

posts-table

2. Таблица unique_likes – необходима для проверки уникальности голосов.
post_id – ключ поста (id в таблице posts).
ip_v4 – ip адрес от дублирования голосов.

unique_likes

Далее создаем файл, который будет содержать класс для подключения к серверу MySQL,
дадим ему имя mysql.php
Код:

<?php

# Параметры MySQL
define("DB_HOST","localhost"); # хост
define("DB_NAME","test_like"); # имя базы
define("DB_USER","user"); # имя пользователя
define("DB_PASS","user_pass321"); # пароль


# класс для работы MySQL
class mySQL {

	public $DBConnect = false;
	
	function __construct(){
		$this->connect();
	}
	
	# подключение к базе
	private function connect(){
		if (@$db = mysql_connect(DB_HOST, DB_USER, DB_PASS)){
			if (mysql_select_db (DB_NAME,$db)){
				mysql_query("SET NAMES 'UTF8'");
				$this->DBConnect = $db;
				return true;
			} else {
				echo 'Не удалось открыть базу данных MySQL: '.mysql_error();
				return false;
			}
		} else {
			echo 'Не удалось соединиться с базой данных MySQL: '.mysql_error();
			return false;
		}
	}

	# выполнение SQL запроса
	# $resType - возвращаемый результат, может быть array/resource
	function query($sql,$resType='array'){
		$res = mysql_query($sql,$this->DBConnect);
		if ($resType == 'resource'){
			return $res; # ресурс
		} else {
			if ($res){
				if (mysql_num_rows($res) > 0){
					while($arr = mysql_fetch_assoc($res)){
						$arRes[] = $arr;
					}
					return $arRes; # массив
				} else {
					return false;
				}
			} else {
				echo 'Ошибка выполнения запроса: '.$sql.mysql_error();
				return false;
			}
		}
	}
}
?>

Создаем страницу, которая будет показываться пользователю, назовём её index.php
Код:

<?php
require_once('mysql.php'); # библиотека для работы с MySQL

$dbObj = new MySQL();

# при успешном запросе, результат будет в виде массива
$arPostsList = $dbObj->query("SELECT * FROM posts");

?>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head>
<body>

<?if (is_array($arPostsList) && count($arPostsList) > 0){?>
<script type="text/javascript">
function doAction(id,type){
	$.post('doAjax.php', {id:id, type:type}, function(data){
		if(isNaN(parseFloat(data))){
		   alert(data);
		}else{
			$('#'+id+'_'+type+'s').text(data);
		}
	});
}
</script>
<?foreach ($arPostsList as $arPost){?>
<div style="border:1px solid #778899;">
	<h2><?=$arPost['name']?></h2>
	<a href="javascript:;" onclick="doAction('<?=$arPost['id'];?>','like');">Нравится (<span id="<?=$arPost['id'];?>_likes"><?=$arPost['like'];?></span>)</a>
	<a href="javascript:;" onclick="doAction('<?=$arPost['id'];?>','unlike');">Не нравится (<span id="<?=$arPost['id'];?>_unlikes"><?=$arPost['unlike'];?></span>)</a>
</div>
<?}

}?>

</body>
</html>

Создаем обработчик, который собственно и будет выполнять всю основную работу, назовём файл doAJAX.php.
Код:

<?php
require_once('mysql.php'); # библиотека для работы с MySQL
$dbObj = new MySQL();

if(isset($_POST['id']) && isset($_POST['type'])){

$arULike = $dbObj->query('
					SELECT * FROM unique_likes
					WHERE post_id="'.(int)$_POST['id'].'"
					AND ip_v4="'.$_SERVER['REMOTE_ADDR'].'"');

	if(!$arULike){

		if ($_POST['type']=='like'){
			
			$dbObj->query('
						UPDATE posts
						SET `like`=`like`+1
						WHERE id="'.(int)$_POST['id'].'"','resource');
			
			$arSNum = $dbObj->query('
							SELECT `like`
							FROM posts
							WHERE id="'.(int)$_POST['id'].'"
							LIMIT 1');

			echo $arSNum[0]['like'];

		} elseif($_POST['type']=='unlike'){

			$dbObj->query('
						UPDATE posts
						SET `unlike`=`unlike`+1
						WHERE id="'.(int)$_POST['id'].'"','resource');
			
			$arSNum = $dbObj->query('
							SELECT `unlike`
							FROM posts
							WHERE id="'.(int)$_POST['id'].'"
							LIMIT 1');

			echo $arSNum[0]['unlike'];

		}
		
		$dbObj->query('INSERT INTO unique_likes (`post_id`,`ip_v4`)
					VALUES ("'.(int)$_POST['id'].'","'.$_SERVER['REMOTE_ADDR'].'")','resource');
	} else {
		echo 'Вы уже проголосовали';
	}
}
?>

Итак, в итоге у нас должны получиться следующие файлы:
mysql.php – файл подключения к БД MySQL.
doAJAX.php – обработчик AJAX запросов.
index.php – страница, показываемая пользователю.

Исходники в архиве:
http://yournet.kz/example/like-unlike/files.rar

Рабочий пример:
http://yournet.kz/example/like-unlike/

Опубликован: 07.02.2013 г.
 
нравится (27 оценок, среднее: 2,85 из 1)
Загрузка...

Комментарии

  1. Андрей пишет:

    А с одной таблицей нельзя сделать?

    1. htmaker пишет:

      Думаю можно, однако хранить такие вещи в разных таблицах более предпочтительнее с точки зрения удобства работы с данными, а так же производительности при большом кол-ве записей в таблицах.

      1. vital пишет:

        А какая может быть проблема с большим количеством даных, если подразумевается, что один посетитель может поставить только один лайк или анлайк? Т.е. с каждым действием у тебя создается одинаковое количество записей в обеих таблицах. Поэтому целесообразней хранить IP в той же таблице, где и лайки, а дальше выбирать по ключам post_id и IP для проверки уникальности

        1. vital пишет:

          Прошу прощения, влез без дела.
          Я проглядел, что posts - это таблица постов, а не самих лайков. :) Просто я представил структуру, где лайки лежат отдельно для разных сущностей. Если данные о кол-ве лайков лежат непосредственно в таблице постов, то конечно структура со второй таблицей - верная.

  2. Абай пишет:

    Спасибо! А как можно сделать для конкретных статей?

    1. htmaker пишет:

      Для статей нужно добавить дополнительный параметр, скажем в таблице со статьями будет поле show_raiting, тип INT(1). Параметр будет отвечать показывать голосование в конкретной статье либо нет. На странице вывода статей делать проверку. Логически 1 - показ, 0 - нет.

  3. Денис пишет:

    Подскажите а можно ли будет сделать так: На стр подгружается инфа допустим название песни которое через некоторое время изменяется и нужно сделать так чтоб названию песни выдавался ид и если юзер нажал на мне нрав или не нрав название этой песни записалась в столбец с названием name в таблице posts и так же выдать ид именно этой песни в таблице unique_likes чтоб когда название песни изменилось и выдало новому названию другой ид можно было поставить нрав или не нрав. Если все это возможно подскажите как заранее большое спасибо!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Каталог сайтов — 4lib.kz

Комментарии

  • Загрузка...

Наверх