Как динамически получать комментарии из базы данных.
Всем привет! В прошлой статье мы рассмотрели, как динамически добавлять комментарии в базу данных, в этой статье мы рассмотрим, как динамически получать комментариии из базы данных.
Суть идеи
Для начала стоит разобраться, как это вообще будет работать.
Итак, у нас есть таблица с комментариями, точно такая же, как и в прошлой статье. Мы сразу при загрузке страницы вызываем функцию, которая отправляет ajax запрос на сервер и переменную count, равную нулю. На сервере мы получаем эту переменную, подключаемся к базе данных и получаем оттуда все записи, у которых id больше нашей переменной(т.е. нуля). Затем мы преобразовываем полученный массив с комментариями в json и отправляем обратно в javascript, где уже и выводим их в нужном нам виде. Переменная count становится равной максимальному id, т.е. последней полученной записи. К примеру, у нас 3 комментария в базе данных, значит переменная count получит значение 3. Дальше мы снова вызываем нашу функцию через какой-то промежуток времени и делаем то же самое, только теперь наша переменная count уже будет равной 3. И так далее...
Реализация
Думаю, суть идеи вы уловили, а теперь приступим к реализации. База данных та же. В папке libs создадим файл get_comments.php с таким кодом:
<?php
header("Content-Type: text/html; charset=UTF-8");
$count = $_POST['count'];
$mysqli = new Mysqli('localhost', 'root', '', 'comments');
$mysqli->query("SET NAMES utf8");
$r = array();
$result = $mysqli->query("SELECT * FROM comm WHERE id > $count");
while($row = $result->fetch_assoc()) {
$r[] = $row;
}
if(empty($r)) {
echo "empty";
} else {
echo json_encode($r);
}
?>
Давайте разберемся, что здесь происходит. Сначала мы устанавливаем правильную кодировку, дальше получаем переменную count, подключаемся к базе данных и устанавливаем правильную кодировку с ней. Создаем пустой массив, получаем данные из базы данных, где id записи больше переменной count, запихиваем все записи в наш пустой массив, делаем проверку, пуст массив или нет, если да, то отправляем клиенту строку empty, иначе же преобразовываем массив с данными в json и отправляем его клиенту.
На сервере все просто. Теперь перейдем к клиентской части, к файлу index.html.
В нем мы подключим файл стилей(main.css), в котором пропишем следующее:
.comments {
border: 1px solid green;
width: 300px;
text-align: center;
border-radius: 5px;
margin: 0 auto 10px;
}
.comments span {
font-family: Tahoma;
}
Особой красоты здесь наводить не будем, не про то статья, но немного покрасивее сделать нужно. Теперь самое интересное - javascript.
<body onload="getComments();">
<script>
function getComments(count = 0) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('post', 'libs/get_comments.php', true);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send('count=' + count);
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
var data = xmlhttp.responseText;
if(data != 'empty') {
data = JSON.parse(data);
for(var i = 0; i < data.length; i++) {
var parent = document.getElementsByTagName('body')[0];
var elem = document.createElement('div');
elem.className = 'comments';
parent = parent.appendChild(elem);
elem = document.createElement('span');
parent.appendChild(elem);
var text = data[i].name;
var textNode = document.createTextNode(text);
elem.appendChild(textNode);
elem = document.createElement('hr');
parent.appendChild(elem);
elem = document.createElement('div');
elem.className = 'comment';
parent.appendChild(elem);
text = data[i].comment;
textNode = document.createTextNode(text);
elem.appendChild(textNode);
var max = data[i].id;
}
count = max;
}
}
}
};
setTimeout(function() {
getComments(count);
}, 3000);
}
</script>
</body>
Не пугайтесь, тут все просто. В body, используя атрибут onload мы сразу вызываем нашу функцию. В нее передается параметр count, который по умолчанию равен 0. Дальше мы используем объект XMLHttpRequest, чтобы подключиться к серверу и указываем верную кодировку. Отправляем переменную count на сервер. Если все прошло успешно, то получаем ответ, проверяем, не равен ли ответ строке empty(что значит, что новых комментариев нет), если нет, то парсим наш json, получаем массив с объектами, прогоняем этот массив в цикле и для каждого комментария создаем html структуру. В конце мы устанавливаем переменную count равной последнему id записи. В конце функции мы устанавливаем таймер, который будет вызывать нашу функцию каждые 3 секунды и передаем ему новое значение переменной count.
Вот так все просто. Это не самое оптимизированное решение, однако, оно очень наглядное и простое.
Итак, всем спасибо за внимание и удачи!
-
- Михаил Русаков
Комментарии (15):
Здравствуйте, Михаил! Браузер ругается на две строчки в последнем скрипте <body onload="getComments();"> и function getComments(count = 0) { что в них такого неправильного непонимаю! Очень жду ответа
Ответить
а какой браузер,будьте так добры,сообщить) и вы ведь должны понимать,что надо вставить не снова <body onload="getComments();">, а в своё body добавить onload="getComments();"
Ответить
браузер google chrome! alexandrdante вставил в свое единственное Body! ошибки выдает такие Uncaught SyntaxError: Unexpected token = а также Uncaught ReferenceError: getComments is not defined
Ответить
а что возвращает не показывает,если смотреть ошибки в консоли через f12 ?
Ответить
alexandrdante как раз через консоль смотрел!
Ответить
вообще последний скрипт можно вставлять в любом месте body? или гдето конкретно?
Ответить
может должно что-то быть прописанно в Head чтобы function getComments(count = 0) { заработала?
Ответить
я пытаюсь воссоздать проблему, так как у себя её не наблюдаю. P.s. код приведён для примера, лучше выучите php + js и всё будет проще
Ответить
alexandrdante занимаюсь веб как хобби!просто обидно пол-дела работает в базе данных я вижу сообщения, но вот с выводом их на страницу блин ну никак не выходит. я так понял, что скрипт не запускается почемуто!
Ответить
ну,у меня вроде всё в порядке, json нормально работает, данные подгружаются. Если получится сымитировать вашу проблему,я вам сообщу
Ответить
спасибо! вот на другом сайте тут нашел такую инфу про такого рода соеденитель с сервером <?php include ('connect.php');?> хотя может это бред моего мозга
Ответить
может полный код шаблона поможет, где здесь ошибка непонимаю!: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <style type="text/css"> .comments { border: 1px solid green; width: 300px; text-align: center; border-radius: 5px; margin: 0 auto 10px; } .comments span { font-family: Arial; } </style> <title>шаблон</title> </head> <body onload="getComments();"> <script> function getComments(count = 0) { var xmlhttp = new XMLHttpRequest(); xmlhttp.open('post', 'libs/get_comments.php', true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send('count=' + count); xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState == 4) { if(xmlhttp.status == 200) { var data = xmlhttp.responseText; if(data != 'empty') { data = JSON.parse(data); for(var i = 0; i < data.length; i++) { var parent = document.getElementsByTagName('body')[0]; var elem = document.createElement('div'); elem.className = 'u770248729_comen'; parent = parent.appendChild(elem); elem = document.createElement('span'); parent.appendChild(elem); var text = data[i].name; var textNode = document.createTextNode(text); elem.appendChild(textNode); elem = document.createElement('hr'); parent.appendChild(elem); elem = document.createElement('div'); elem.className = 'comment'; parent.appendChild(elem); text = data[i].comment; textNode = document.createTextNode(text); elem.appendChild(textNode); var max = data[i].id; } count = max; } } } }; setTimeout(function() { getComments(count); }, 3000); } </script> <form action="" method="post"> <span>Имя: </span><br> <input type="text" id="name"><br> <span>Комментарий</span><br> <textarea id="comment" cols="30" rows="10"></textarea><br> <button id="button">Отправить</button> </form> <script> var button = document.getElementById('button'), xmlhttp = new XMLHttpRequest(); button.addEventListener('click', function() { var name = document.getElementById('name').value.replace(/<[^>]+>/g,''), comment = document.getElementById('comment').value.replace(/<[^>]+>/g,''); if(name === '' || comment === '') { alert('Заполните все поля!'); return false; } xmlhttp.open('post', 'libs/add_comment.php', true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send("name=" + encodeURIComponent(name) + "&comment=" + encodeURIComponent(comment)); }); </script> </body> </html>
Ответить
Fatal error: Call to undefined function fetch_assoc() in /home/www/cupoma58.ru/comment/index.php on line 70
Ответить
Возник вопрос если переменной count присваивается max и это значение передается в функцию getcomments(count = 0) то ведь переменная count станет равна 0 тогда зачем туда передавать значение ? или данная запись (getcomments(count = 0)) значит что если никакого значения не передано то тогда 0 ?
Ответить
Нашёл вроде две ошибки 1) setTimeout - это таймер задержки. (В конце функции мы устанавливаем таймер, который будет вызывать нашу функцию каждые 3 секунды...) 2) В цикле while не указано условие выхода. ( while($row = $result->fetch_assoc()) { $r[] = $row; } )
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.