Найти в Дзене

Как сделать чат на PHP + JavaScript (Без AJAX), который будет обновляться в реальном времени

Всем привет. Сегодня я вам покажу, как сделать чат, который будет обновляться в режиме реального времени на PHP и JavaScript без AJAX и прочих дополнений. Только чистый JS и PHP, всё, как я люблю 😁 Начинаем У меня есть вот такой сайт, где я уже заранее сделал регистрацию, авторизацию, вёрстку чата, а также базу данных, где будут храниться данные о пользователях и сообщениях в чате. Для начала нужно реализовать загрузку сообщений из базы данных в чат. Пишем PHP код, который будет получать все эти записи и через цикл их выводить в виде HTML кода Создаём цикл и в него переносим код сообщения Пока получается это В этот код вставим переменные, полученные из записей базы данных. Для начала вставим текст сообщений Дальше нам нужно вставить имя пользователя, но тут не всё так просто. Мы подключаемся к таблице с информацией о сообщениях, в которой есть только такие данные: Мы можем посмотреть только id пользователя. А нам нужно по этому id получить его имя Это можно сделать через SQL запрос.
Оглавление

Всем привет. Сегодня я вам покажу, как сделать чат, который будет обновляться в режиме реального времени на PHP и JavaScript без AJAX и прочих дополнений. Только чистый JS и PHP, всё, как я люблю 😁

Начинаем

1. Создаём чат

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

-2
-3
-4

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

-5

Создаём цикл и в него переносим код сообщения

-6

Пока получается это

-7

В этот код вставим переменные, полученные из записей базы данных. Для начала вставим текст сообщений

-8
-9

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

-10

Мы можем посмотреть только id пользователя. А нам нужно по этому id получить его имя

-11

Это можно сделать через SQL запрос. Только не пугайтесь, запрос получается вот таким вот длинным. Но если захотеть, разобраться можно

-12

Этот запрос берёт нашу обычную таблицу "chat" и объединяет её с таблицей "user". Но не просто объединяет, этот запрос добавляет колонку "username", где id пользователей в двух таблицах совпадают. Если коротко, по таблице "user" запрос подставляет им username.

-13

Получается это так.

Но я бы не только взял username, я бы ещё взял бы параметр textname

-14

После того, как мы попробовали SQL запрос в базе данных, можно применять его и в нашем коде

-15

Вот, замечательно. Уже что-то адекватное

-16

Теперь надо сделать так, чтобы сообщения можно было отправлять

-17

Нужно создать PHP файл, через который мы будем отправлять данные из этой формочки на сервер

-18

Пишем код. Отправляем данные на сервер и возвращаемся обратно в chat.php

-19

Наш чат уже заработал, но, чтобы отправить сообщение, нужно нажать на кнопку в форме, которая перекидывает вас на другую страницу, быстро выполняет код и возвращает в чат. Происходит это быстро, но страница всё равно обновляется.

-20

Если сообщения не отправлять, а читать, то страница сама по себе обновляться не будет, и в чате останутся старые сообщения. Чтобы читать новые, нужно постоянно обновлять страницу, что очень неудобно.

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

Лично я, когда был новичком в этом деле, пытался эту проблему решить, и когда я искал способы, постоянно натыкался на ответы, где люди писали про AJAX. Мне очень хотелось написать код без использования сторонних ресурсов, только на чистом JS и PHP, это можно легко реализовать, о чём я напишу в следующем заголовке

-21

В чате есть небольшая проблема, при загрузке страницы, он пролистывается в самое начало, а должен быть пролистнут в самый конец.

Чтобы это исправить, пишем вот такой код

-22

Этот код, после загрузки DOM дерева (это нужно, чтобы он применялся, когда чат полностью загрузится) задаёт прокрутку чата и прокручивает в самый низ.

2. Обновление сообщений в режиме реального времени

Теперь нам нужно сделать обновление сообщений в режиме реального времени.

-23

Объясняю. Нам нужно сделать код, который после первой загрузки наших сообщений при открытии чата, будет сравнивать, не появились ли в базе данных сообщения с датой, которая наступила позже, чем последнее наше обновление чата. После чего мы должны будем загрузить эти сообщения и добавить их в HTML.

Можно было бы сделать это проще и просто сделать код, который каждый раз перезагружал все эти сообщения заново, но так делать будет не разумно, каждый раз обращаться к базе данных и менять HTML разметку это лишняя нагрузка на сервер и устройство пользователя. Поэтому делать будем по-умному.

В SQL запросе можно сравнивать даты так. Когда я первый раз узнал, то был очень удивлён

-24

Пишем скрипт на JS. Создаём переменную, куда после загрузки страницы записываем время последнего обновления чата (в миллисекундах) (1773933612266)

-25

Создадим функцию load_chat, которая будет выполняться каждую секунду. Эта функция будет отправлять запрос в файл loadchat.php, который будет уже связываться с базой данных

-26

Так... Что мы делаем дальше? Подготовьтесь, возможно, будет немного сложно, если у вас плохо с JavaScript

-27

Через fetch мы отправляем запрос в файл loadchat.php, но теперь в коде появились изменения, что я сделал?

Я сделал так, чтобы мы могли передавать параметры в файл loadchat.php. Я создал объект URLSearchParams, через который можно передавать параметры так, как будто мы их отправили через форму HTML, там можно использовать GET и POST методы. В этот объект я добавил параметр time, в который записал значение времени. После чего я обновил fetch запрос, добавил туда body, который содержит эти параметры, и информацию о методе передаче (POST).

Метод fetch срабатывает не сразу, должно пройти какое-то время, возможно незначительное. Мы не может просто вызвать этот метод и сразу вытащить из него результат, нужно на это время. Поэтому наш код сначала попытается сделать запрос, потом попытается из пустого результата вытащить данные, а уже потом выполнится сам запрос. Чтобы это исправить, я сделал нашу функцию асинхронной (async) и добавил await перед fetch, await будет заставлять наш код ждать результаты этой функции. Await работает только в асинхронной функции, если интересно, поизучайте дополнительно.

-28

Внутри PHP мы можем получать наши значения, и делается это довольно просто, как в формах.

В нашей таблице время выглядит вот так

-29

Нужно преобразовать миллисекунды в это

-30

Создаём объект DateTime, потом туда закладываем наше время. Просто время в миллисекундах туда положить нельзя, нужно в секундах, поэтому делим на 1000 и округляем.

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

-31

Результаты подсчёта мы выведем на экран.

В самом JS мы получим результат отправки запроса в loadchat.php, преобразуем в текст и выведем в консоль

-32

Чтобы проверить наш код, откроем вторую вкладку, набросаем туда сообщений и посмотрим, что выведет наш код

-33

Наш код показывает, что новых сообщения у нас два.

-34

Теперь сделаем загрузку самих сообщений.

Дальше даже не знаю. Как бы вам это всё понятнее объяснить.

-35

Мы меняем цикл со счётчиком на цикл, который будет генерировать HTML код новых сообщений и сохранять его в переменную html. При этом важно не забывать, что чтобы через запрос получить не только id автора сообщения, но и его ник, нужен более сложный запрос. Я уже показывал, как это написать, можете вернуться, пролистать статью наверх и посмотреть. Только к этому запросу мы добавляем условие `date` > '$time'.

В итоге получается запрос, который выводит таблицу с новыми сообщениями + ником автора (ника автора в таблице "chat" нет, только его id)

И так, надеюсь, вам было понятно... охх...

Этот самый цикл мы выводим и получаем через JS.

А вот здесь ещё один интересный момент. Теперь мы наш HTML код должны вставить в нашу разметку

-36

Я решил вынести переменную chat за функцию для удобства.

После нашего запроса и получения HTML кода, мы должны правильно вставить его в разметку. Если мы напрямую используем innerHTML, чтобы вставить HTML код, то наш элемент чата будет криво обновляться. Его разметка будет переделываться и могут возникнуть трудности, например, нельзя будет выделять сообщения, каждую секунду чат будет обновляться и переделывать свою HTML разметку, выделение будет сбиваться.

-37
-38

Поэтому мы сделаем так. Мы создадим через createElement новый элемент и запишем его в messages. После чего применим innerHTML к отдельному элементу и загрузим сообщения. После чего через appendClild мы аккуратненько загрузим этот элемент в чат, и не будет никаких багов, вроде.

Также не забываем менять переменную time и сбрасывать таймер.

-39

Ну а также после обновления не забываем прокручивать чат вниз.

Я открыл две вкладки и попробовал отправить сообщение в одном чате, а принять в другом, работает!!

-40

А теперь финальный штрих

3. Делаем отправку сообщений без обновления страницы

Сделать отправку сообщений можно по тому же принципу, что и их загрузку.

-41

Пишем вот такой удивительный код. Мы подключаемся к нашей форме, получаем событие отправки данных и через функцию preventDefault() отправку данных отменяем. Вместо этого мы можем добавить свои функции.

-42

Также создаём объект URLSearchParams, загружаем в него значение элемента textarea и отправляем его так, как будто мы это отправили из той же формы. Только очистить элемент textarea не забудьте

И получается вот так

-43

Наш чат начал работать, ура!!

Подводим итоги

Мы сделали чат, который обновляется в режиме реального времени, а также отправляет сообщения без перезагрузки, и сделали всё это на чистом PHP и JavaScript.

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

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

Ну а я надеюсь, что вы оцените, поставите лайк, оставите комментарий, а может быть даже и подпишитесь))