Помогите пожалуйста разобраться. Постараюсь кратко описать суть скрипта. setInterval каждую секунду выполняет функцию, которая пост запросом отправляет текущее локальное время в формате чч:мм:сс на скрипт, который делает запрос в БД. В БД поля id, name, time, text (1, Alex, 12:13:14, Привет). Скрипт если в базе найдена запись по текущему времени возвращает ответ {"name":[name],"time":[time],"text_message":[text]} дальше JSON.parse парсит ответ сервера и на странице в конец контейнера вставляет полученные данные. так вот проблема в том, что если в БД есть две записи от одного и того же времени, секунда в секунду, то ответ от сервера будет в 2 строки, и JSON.parse уже не работает. Как сделать, чтобы он парсил обе строки, и вставлял в конец контейнера обе и более записи? HTML: <!doctype html> <html> <head> <meta charset="UTF-8"> <title>VOI</title> <style> .block {width:300px; height:auto; margin:0 auto;} </style> <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> <script> function addZero(i) { if (i < 10) { i = "0" + i; } return i; } function cron() { var date = new Date(); var time = addZero(date.getHours()) + ':' + addZero(date.getMinutes()) + ':' + addZero(date.getSeconds()); $.post("http://testscript.ru/voi/sql.php", { time: time }, function(data) { if (!data) { console.log("действие"); } else { var user = (data); user = JSON.parse(user); $('#alert').prepend('<!--insert--><div style="padding:10px 0; border-bottom:1px dashed #bdc3c7; background-color: transparent;"><div style="width:30px; height:30px; float:left;"><div class="ava"></div><div style="clear:both;"></div></div><div style="width:360px; height:auto; float:left;"><div style="padding:0 15px; font-size:14px; color:#626161;"><font style="font-weight:700;">'+user.name+'</font> <font style=" font-size:12px; color:#bdc3c7;">написал в '+user.time+'</font></div><div style="padding:5px 15px; font-size:14px; color:#626161;">'+user.text_message+'</div><div style="color:#bdc3c7; font-size:11px; text-align:right; padding-top:5px;"></div></div><div style="clear:both;"></div></div><!--/insert-->'); } }); } setInterval(cron, 1000); </script> </head> <body> <div class="block"> <div id="alert"></div> </div> </body> </html> sql.php PHP: $dat = $_POST['time'];$dat = trim($dat);$dat = htmlspecialchars($dat);$link = mysqli_connect("localhost", "root", "1234", "voi");if (mysqli_connect_errno()) { printf("Соединение не установлено: %s\n", mysqli_connect_error()); exit();}if (!empty($dat)) { mysqli_set_charset($link, "utf8"); $query = "SELECT * FROM messages WHERE time='$dat'"; $result = mysqli_query($link, $query); while ($row = mysqli_fetch_assoc($result)) { echo "{\"name\":\"".$row['name']."\",\"time\":\"".$row['time']."\",\"text_message\":\"".$row['text']."\"}\n"; } mysqli_close($link);}
@bologer у меня есть чат, мне надо чтобы в определённые дни и время туда вставлялись нужные мне сообщения
Ты хочешь чтобы без твоего нахождения на сайте "в определенные дни и время туда вставлялись сообщения"? Если да, то лучше крон сделать, а уже со стороны клиента setInterval который будет обновлять сообщения в чате. А вообще я бы порекомендовал использовать socket.io для чата, с ajax это насилие сайта, тем более если ты делаешь запросы каждую секунду.
@bologer крон не работает ежесекундно, там же вроде минимум 1 минута интервалы. или я ошибаюсь? да и на нагрузку пофиг, с этим проблем не будет. я это-то сделал "на коленке" т.к. в js вообще ничего не понимаю, только синтаксис да интуитивно. поэтому хочется уже решить проблему так, как начал, закончить, и другими делами заняться)) help готов к донату на киви или вэбмани))
Проблема у тебя не в JSON.parse а в этом куске Code: while ($row = mysqli_fetch_assoc($result)) { echo "{\"name\":\"".$row['name']."\",\"time\":\"".$row['time']."\",\"text_message\":\"".$row['text']."\"}\n"; }
Чтобы тебе вывести больше чем одну запись нужно: PHP: $result = mysqli_query($link, $query); while ($row = mysqli_fetch_assoc($result)) { echo "{\"name\":\"".$row['name']."\",\"time\":\"".$row['time']."\",\"text_message\":\"".$row['text']."\"}\n"; } заменить на PHP: $result = mysqli_query($link, $query);echo json_encode($result);} в если post будет успешным , тогда выведи все данные в консоль, которые ты вытащил из базы с — console.log(data). парси JSON и верни обратно в data - data = JSON.parse(data) используй forEach() или for() цикл, чтобы append() каждую новую запись из объекта в контейнер (о котором ты говоришь в этом посте) HTML: function(data) { if (!data) { console.log("действие"); } else { data = JSON.parse(data); console.log(data); // смотри в консоль, что выводится, чтобы понимать формат данных // и потом уже когда ты понял, что у тебя там - выводи их, например: data.username, data.id // for(var i = 0; i <= data.length - 1; i++) { // console.log(data[i].id); // console.log(data[i].username); // } } }); Можно тебе JS чуть нужно будет поменять так как я не знаю как у тебя выглядят данные. Посмотри в консоли и уже от этого отталкивайся. P.s. При SELECT запросе в базу, выбери только те поля которые тебе действительно нужны, например "SELECT `id`, `username`, `message`", чтобы при ответе с сервера у тебя не показывало лишней информации. Я сейчас крайне занят, нашел минутку, чтобы тебе помочь.
Сделай так Code: $arr = []; while ($row = mysqli_fetch_assoc($result)) { $arr[] = [ 'name': $row['name'], ... ... ... ]; }; echo json_encode($arr);
сменил для дебага пост на гет, чтобы прямо с браузера отправлять данные. В общем отправляю гетом 11:18:20, в базе 2 записи под этим временем. PHP: <?php$dat = $_GET['time'];$dat = trim($dat);$dat = htmlspecialchars($dat);$link = mysqli_connect("localhost", "root", "1234", "voi");/* проверка соединения */if (mysqli_connect_errno()) { printf("Соединение не установлено: %s\n", mysqli_connect_error()); exit();}if (!empty($dat)) { mysqli_set_charset($link, "utf8"); $query = "SELECT * FROM messages WHERE time='$dat'"; $result = mysqli_query($link, $query); while ($row = mysqli_fetch_assoc($result)) $resp[] = $row; $done = json_encode($resp, JSON_UNESCAPED_UNICODE); if ($done == "null") { mysqli_close($link); die; } else { print $done; } mysqli_close($link);}?> ответ Code: [{"ID":"269","name":"Ваня","time":"11:18:20","text":"Привет Женя"},{"ID":"270","name":"Сергей","time":"11:18:20","text":"Привет Женёк"}] дальше пытаюсь в консоль вывести полученные данные, и получаю 2 раза по 4 ответа (undefined). почему? HTML: function addZero(i) { if (i < 10) { i = "0" + i; } return i; } function cron() { var date = new Date(); var time = addZero(date.getHours()) + ':' + addZero(date.getMinutes()) + ':' + addZero(date.getSeconds()); $.post("http://testscript.ru/voi/script.php", { time: time }, function(data) { if (!data) { console.log("действие"); } else { data = JSON.parse(data); for (var i = 0; i <= data.length - 1; i++) { console.log(data.ID); console.log(data.name); console.log(data.time); console.log(data.text); } /* var user = (data); user = JSON.parse(user); $('#alert').prepend('<!--insert--><div style="padding:10px 0; border-bottom:1px dashed #bdc3c7; background-color: transparent;"><div style="width:30px; height:30px; float:left;"><div class="ava"></div><div style="clear:both;"></div></div><div style="width:360px; height:auto; float:left;"><div style="padding:0 15px; font-size:14px; color:#626161;"><font style="font-weight:700;">'+user.name+'</font> <font style=" font-size:12px; color:#bdc3c7;">написал в '+user.time+'</font></div><div style="padding:5px 15px; font-size:14px; color:#626161;">'+user.text_message+'</div><div style="color:#bdc3c7; font-size:11px; text-align:right; padding-top:5px;"></div></div><div style="clear:both;"></div></div><!--/insert-->'); */ } }); } setInterval(cron, 1000); @bologer спасибо что заглядываешь и подсказываешь
1. Ты сказал что передаешь данные через GET, что и видно в php скрипте, а на клиенте у тебя $.post, смени на $.get 2. ОБЯЗАТЕЛЬНО перед селектом добавь Code: $dat = mysqli_real_escape_string($link, $dat); иначе будет возможна SQL инъекция 3. четыре undefined это отсюда: Code: for (var i = 0; i <= data.length - 1; i++) { console.log(data.id); console.log(data.name); console.log(data.time); console.log(data.text_message); } там у тебя все 4 будут undefined так как ты время через POST передаешь.
@kranx да это я для дебага менял на гет чтобы отправить данные удобнее было undefined это уже когда гет на пост заменён
все, понял. вот как надо Code: for (var i = 0; i <= data.length - 1; i++) { console.log(data[i].ID); console.log(data[i].name); console.log(data[i].time); console.log(data[i].text_message); }
напиши "console.log(data)" в JS СНАРУЖИ цикла и отправь сюда результат, чтобы понимать, что тебе вообще возвращается обратно. Скорее всего ты не правильно выводишь данные и из-за этого не могу тебе точный вариант написать. Точно, совсем забыл дописать позиции i для каждого ряда UPD: исправил изначальный ответ, чтобы не путать людей.