Реалізація сторінки коментарів

серпень 2015

Зміст

  1. Про коментарі
  2. Декілька слів про роботу кодів сторінки коментарів, що ми взагалі хотіли б реалізувати?
  3. Структура блоків веб-сторінки коментарів. - Але все ж, як воно працює?
  4. Проста Html-форма
  5. Скрипт організації випадкових питань
  6. Скрипт організації затримки повідомлень на сорок секунд
  7. Вносимо дані коментаря в таблицю
  8. Виводимо коментарі

1. Про коментарі

Від себе:

Як початківець в програмуванні, вчу Бази Даних,... як практична робота реалізував собі простеньку веб-сторінку для зворотнього звязку,- імя, коментар, і, будь-ласка, можете залишати повідомлення... Але натрапив на мій ресурс спамер чи хто він там і отримуй пане Анатолію "кучу малу" (більше тисячі) сторонніх повідомлень.

Що ж... добра нагода для нової практичної роботи,- проста сторінка коментарів з елементами захисту від спамерів...




Напевно ж не варто розповідати наскільки поширеними є веб-сторінки з коментарями відвідувачів веб-сайту.

Думка відвідувача веб-ресурсу цікава як для адміністротора сайту, так і для пересічних відвідувачів ресурсу.

Все то добре, але ж крім добрих порядних відвідувачів є особистості, які не зовсім за призначенням застосовують коментарі, - спамери, чи навіть програмки-боти, ціль яких зовсім не не інформативний коментар, а рандомний текст із посиланнями на сторонні ресурси. Скажімо, в спамера своя ціль і його ціль зовсім не схожа з думкою адміністратора веб-ресурсу, де він "смітить" своїми коментарями. Що ж казати, такі собі спамери надокучають і вимагають від розробника сторінки коментарів, додаткових заходів, щоб хоча б зменшити кількість сторонніх неінформативних повідомлень.

2. Декілька слів про роботу кодів сторінки коментарів, що ми взагалі хотіли б реалізувати?

  1. Ну по-перше, звісно, основне то коментар, далі в любому коментарі хотілось би бачити власника коментаря - імя, також було б інформативно, дата та час повідомлення. Вважаю, цього досить.
  2. Друге, антиспамерний захист, звісно це дещо незручно для зацікавленого відвідувача, але вважаю, тут варто йти на компроміс між зручністю відвідувача та адміністратора веб-ресурсу.
    1. Що ж до захисту, часова затримка повторного повідомлення; скажімо в 40 секунд, тобто слідуюче повідомлення можна буде внести в таблицю бази даних не раніше ніж за 40 секунд. Чому саме 40 секунд? Я поставив на власний розсуд, ніби й не довго, але й не так швидко, - а так звісно варто враховувати інтенсивність повідомлень на сторінці кометарів, якщо в мене наразі 1-3 повідомлення в місяць то, вважаю, така затримка є допустимою.
    2. По-друге, є звісно такий елемент захисту, як капча, але я для початку вирішив зробити антибот-питання, що рандомно виводяться у html-форму сторінки коментарів. Ну не знаю, питання підібрав з легким гумором, мені так цікаво, може і для пересічного відвідувача це буде легкою компенсацію за незручність, що додатково приходиться відповідати ще й на запитання. (На зразок, "Що з землі легко піднімеш, але далеко не закинеш ? Бабусю, Себе, Пух, Кішку"... ).
    3. Третє, обмеження кількості символів коментаря. Особисто вважаю 400 символів досить, щоб висловити свою думку чи побажання. В крайньому разі людина напише ще один коментар :)
  3. Якщо ж некоректно введені дані, то скрипт направляє відвідувача на веб-сторінку з попередженням, на зразок цієї.
Girl question

3. Структура блоків веб-сторінки коментарів. - Але все ж, як воно працює?

- Звісно можна сказати декілька слів про те, які взаємозв'язки між основними блоками при реалізації сторінки коментарів.

Переглянемо малюнок.

Coment Page structure

Рис.1. Структура взаємозвязків основних блоків сторінки коментарів.

Якщо в декількох словах і просто, то можливо десь так:

4. Проста Html-форма

1. Проста Html-форма має:
- поле для введеня імені - input required type="text" name="name",
- поле для введення коментаря - textarea required cols="55" rows="8" name="comment"
- ну і кнопочку відправити меседж input type="submit" value="Надіслати відгук".

Сама форма всі дані, що ввів відвідувач відправляє до скрипту Php-обробника, що звісно на стороні серверу, там ми виконуємо перевірку, чи всі дані коректно введено, берем час внесення повідомлень і якщо все гаразд, то всі дані відправляємо в таблицю Бази Даних.

5. Скрипт організації випадкових питань.

2. Поле форми має додатковий захист від спамерів, застосуванням випадкових питань. В Базі Даних створена окрема таблиця, де є десяток питань і php-скрипт виводить одне випадкове питання.

Реалізовано це слідуючим чином: в полі форми є поля, які формуються php-скриптом, у форму передається:
- питання,
- ряд варіантів відповіді,
- id питання в прихованому полі.

Вигляд Html-форми:

<p>Гітлера звали …?</p>
<input name="question" type="radio" value="1" checked>Хайль
<input name="question" type="radio" value="2">Адольф 
<input name="question" type="radio" value="3">Шикльгрубер
<input name="question" type="radio" value="4">Володимир
<input name="id_question" type="hidden" value="7">

Вигляд Html-форми, що формується Php-скриптом:

<?php
$mysqli = new mysqli("localhost","user","password","DB");
// Встановлюємо тип кодування/передачі символів - utf8
mysqli_set_charset($mysqli, "utf8");
$res = $mysqli->query("SELECT * FROM `chat_question` 
				ORDER BY RAND() LIMIT 1");
$row = $res->fetch_assoc(); 
echo '<p>  '.$row["question"].'<br>
<input name="question" type="radio" value="1" checked>'.$row["1_answer"].'
<input name="question" type="radio" value="2">'.$row["2_answer"].' 
<input name="question" type="radio" value="3">'.$row["3_answer"].'
<input name="question" type="radio" value="4">'.$row["4_answer"].'
<input name="id_question" type="hidden" value="'.$row["id"].'"></p>';		        
?>

Відвідувач вибравши вірний варіант, звісно заповнивши поле імя та коментар відправляє дані на сервер, => скрипт в свою чергу отримавши id-питання перевіряє правильну відповідь, що записана в таблиці Бази Даних.

Частина коду php-обробника форми, що перевіряє правильні відповіді

$res = $mysqli->query("SELECT true_answer FROM `chat_question` WHERE id='$id_question'");
$row = $res->fetch_assoc(); 
if ($row["true_answer"]!==$answer){
	header('Location: Warning_Page.php');
	exit;			
};

Якщо відповідь не правильна, тоді зрозуміло ніякі коментарі, дані в таблицю коментарів не вносяться.

А так... пригадав все ж для зручності відвідувача, прийшлось застосовувати javascript - Local Storage, дещо про Local Storage а ж раптом відвідувач не знає відповіді на моє каверзне запитання... і що знову писати меседж?...
-Та ні, не прийдеться, текст повідомлення зберігся в пам'яті і поле форми коментаря буде автоматично заповнене,... варто лиш буде все таки правильно дати відповідь на питання...

6. Скрипт організації затримки повідомлень на сорок секунд.

3. Часове обмеження повідомлень. Робота з часом це цікаво, і як на мене, то не завжди це просто, ось, наприклад, деякі особливості роботи з часом в PHP.Та до справи...

Кожне повідомлення має час внесення в таблицю бази даних. Час формується в php-обробнику та вноситься в таблицю БД. Як пам'ятаємо обмеження в нас 40 секунд, тому вибираємо з таблиці останнє повідомлення - SELECT MAX(Msg_DateStamp)FROM Table_Coment та вираховуємо різницю часу з новим коментарем.

// Час в форматі DateStamp, щось на зразок (1440434070)
$t=time();
				
//Вибираємо останній допис з таблиці коментарів
$result = $mysqli->query("SELECT MAX(Msg_DateStamp)
			FROM Table_Coment)");
$row = $result->fetch_assoc();
		
//Рахуємо різницю часу в 40 секунд
$Diff_Time=$t-$row['Msg_DateStamp'];
	        
// Якщо різниця < 40 секунд, то відмовляємо у внесенні повідомлень
if ($Diff_Time<40){
	$Access=false;
	$Msg="Sorry You cant write message :(";
}else {$Access=true;
};   
		

Єдине...
варто врахувати, що час має рахуватись для одного і того ж відвідувача, тому маємо ще й ідентифікувати цього відвідувача, для цього застосуємо сесії.

Документація вказує, що перед початком роботи з сесіями варто вказати спочатку роботи скрипту:

<?php
session_start();
// подальші коди php-скрипту....

Сесія має унікальний "ключ", щось на зразок 8dbr4s45rdh3s59jlr4qffdr16 - цей "ключ" знаходиться як на стороні клієнта, так і на сервері, це нам дає можливість реалізувати такий алгоритм ідентифікації відвідувача:
- Якщо існує "ключ" сесії і він має секретне значення,( в моєму випадку змінна Hash ), що зберігається в таблиці коментарів Table_Coment, => то перевіряємо, коли ж відвідувач вносив повідомлення ( час у форматі DateStamp, щось на зразок -1440434070 )
- Якщо ж такої сесії немає, відвідувач заходить вперше, то просто створюємо новий "ключ" для нового відвідувача та просто вносимо повідомлення в таблицю коментарів Table_Coment.

Ну звичайно це трошки збільшує код php-обробника...

// Час в форматі DateStamp, щось на зразок (1440434070)
$t=time();
		
// якщо існує дані сесії
if(isset($_SESSION["user_label"])){
		
//  беремо значення та час останнього повідомлення сесії із БД
$Existing_Hash=$_SESSION["user_label"];	
$result = $mysqli->query("SELECT id, Time_Coment, Msg_DateStamp FROM Table_Coment
			 WHERE Hash='$Existing_Hash' 	
			 AND Msg_DateStamp=(SELECT MAX(Msg_DateStamp) 
				 	FROM Table_Coment)");
$row = $result->fetch_assoc();	
	        
//Рахуємо різницю часу в 40 секунд
$Diff_Time=$t-$row['Msg_DateStamp'];
	        
// Якщо різниця < 40 секунд, то відмовляємо у внесенні повідомлень
if ($Diff_Time<40){
$Access=false;
$Msg="Sorry You cant write message :(";
}else {$Access=true;
};    

// заносимо повторно існуючий session key в базу даних
$session_value=$Existing_Hash;
	
// якщо сесія ще не існує, то відповідно створюємо нову сесію  
}else {  
$_SESSION["user_label"] = generateCode(6);
$session_value=$_SESSION["user_label"];
$Access=true;
};   

Добавлю, значення для сесії формується випадковим чином, ось таким от скриптом generateCode():

function generateCode($length) {
	$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHI JKLMNOPRQSTUVWXYZ0123456789";
	$code = "";
	$clen = strlen($chars) - 1;  
	while (strlen($code) < $length) {
        	$code .= $chars[mt_rand(0,$clen)];  
	}
	return $code;
};

7. Вносимо дані в таблицю Table_Coment

Після відповідних перевірок, php-обробник вносить відповідні дані в таблицю Table_Coment, SQL-запит на внесення даних:

if ($Access){
  $mysqli->query("INSERT INTO `Table_Coment`(`Name`,`Date_Coment`,`Time_Coment`,`Coment`,`Hash`,`Msg_DateStamp`) 
        	VALUES ('$name','$Msg_Date_To_DB','$Msg_Time_To_DB','$comment','$session_value','$t')");
}

8. Виводимо коментарі

Php-скрипт, що формує Html-сторінку в частині виведення коментарів на сторінку:

$result = $mysqli->query("SELECT * FROM `Table_Coment` 
			ORDER BY Msg_DateStamp");	
for ($row_no = $result->num_rows - 1; $row_no >= 0; $row_no--){
	$result->data_seek($row_no);
	$row = $result->fetch_assoc();
	echo '<p>'.$row['Name'].' '.$row['Date_Coment'].' '.$row['Time_Coment'].' '.$row['Coment'].'</p>';
};


- Що ж, на цьому завершу свою статтю про сторінку коментарів. Бажаю всім відвідувачам гарного дня і... успіхів в кодуванні, if You (isset(Coder)) :)

P.S. Якщо в тексті чи кодах є помилки, чи щось, аж занадто суперечливе для логіки справжніх програмістів, що ж можете залишити своє зауваження на моїй сторінці коментарів. Анатолій