Pull to refresh

Простой чат на JavaScript и PHP

Привет, Хабраюзеры! Хочу поделиться с вами своим опытом. Сегодня я расскажу, как написать простой чат на php и javascript.
Под катом много кода. Приготовитесь…

Я использовал MySQL базу данных для хранения сообщений чата. Для начала, создадим новую базу в phpMyAdmin. И импортируем туда небольшую таблицу.
  1. CREATE TABLE IF NOT EXISTS `chat` (
  2.   `id` int(15) NOT NULL AUTO_INCREMENT,
  3.   `name` varchar(30) NOT NULL,
  4.   `text` text NOT NULL,
  5.   PRIMARY KEY (`id`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

Далее, создаем новый документ и называем его index.php. Именно этот документ будет основным. Проще говоря, в нем будет наш чат.
Для чата я использовал jQuery и несколько плагинов для него.
Подключим jQuery и имеющиеся плагины…
  1. <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
  2. <script type="text/javascript" src="js/jquery.timers.js"></script>
  3. <script type="text/javascript" src="js/jquery.cookie.js"></script>

Затем, сверстаем разметку для нашего чата.
  1. <style>
  2. #msg-box{overflow:auto; width:750px; height:300px; border:1px solid black; padding:5px; margin:0px; display:inline-block; background:#FFF; margin:32px 0 0 32px;}
  3. #msg-box ul{list-style:none; padding:0px; margin:0px;}
  4. #t-box{margin-left:32px;}
  5. </style>
  6.  
  7. <div id="msg-box">
  8.   <ul>
  9.   </ul>
  10. </div>
  11. <form id="t-box" action="?" style="">
  12.   Имя: <input type="text" class='name' style="width:100px;" >
  13.   <input type="text" class='msg' style="width:500px;" >
  14.   <input type="submit" value="Отправить" style="margin-top:5px;">
  15. </form>

Итак, готова разметка для чата, таблица для хранения сообщений чата. Теперь, мы напишем серверный скрипт для обработки сообщений. Скрипт должен уметь сохранять и раздавать сообщения. Создаем новый документ и назовем его chat.php
Содержание chat.php:
  1. <?
  2. //Функции для работы с БД
  3. function getQuery($query){
  4.   $res = mysql_query($query) or die(mysql_error());
  5.   $row = mysql_fetch_row($res);
  6.   $var = $row[0];
  7.   return $var;
  8. }
  9.  
  10. function setQuery($query){
  11.   $res = mysql_query($query) or die(mysql_error());
  12.   return $res;
  13. }
  14.  
  15. //Соединяемся с базой
  16. @mysql_connect('localhost', 'root', '') or die("Не могу соединиться с MySQL.");
  17. @mysql_select_db('best') or die("Не могу подключиться к базе.");
  18. @mysql_query('SET NAMES utf8;');
  19.  
  20. switch($_GET["event"]){
  21.   //Тут раздаем последние сообщения
  22.   case "get":
  23.     //Сколько сообщений раздавать пользователям
  24.     $max_message = 60;
  25.     //Всего сообщений в чате
  26.     $count = getQuery("SELECT COUNT(`id`) FROM `chat`;");
  27.     //Максимальный ID сообщения
  28.     $m = getQuery("SELECT MAX(id) FROM `chat` WHERE 1");
  29.     //Удаление лишних сообщений.
  30.     //Если хотите, чтобы сохранялась вся история, смело сносите этот кусочек
  31.     if($count > $max_message){
  32.       setQuery("DELETE FROM `chat` WHERE `id`<".($m-($max_message-1)).";");
  33.     }
  34.     //Принимаем от клиента ID последнего сообщения
  35.     $mg = $_GET['id'];
  36.     //Генерируем сколько сообщений нехватает клиенту
  37.     if($mg == 0){$mg = $m-$max_message;}
  38.     if($mg < 0){$mg = 0;}
  39.     $msg = array();
  40.  
  41.     //Если у клиента не все сообщения, отсылаем ему недостоющие
  42.     if($mg<$m){
  43.       //Берем из базы недостобщие сообщения
  44.       $query = "SELECT * FROM `chat` WHERE `id`>".$mg." AND `id`<=".$m." ORDER BY `id` ";
  45.       $res = mysql_query($query) or die(mysql_error());
  46.       while($row = mysql_fetch_array($res)){
  47.         //Заносим сообщения в массив
  48.         $msg[] = array("id"=>$row['id'], "name"=>$row['name'], "msg"=>$row['text']);
  49.       }
  50.     }
  51.     //Отсылаем клиенту JSON с данными.
  52.     echo json_encode($msg);
  53.   break;
  54.  
  55.   case "set":
  56.     //Принимаем имя.
  57.     $name = htmlspecialchars($_GET['name']);
  58.     //Принимаем текст сообщения
  59.     $msg = htmlspecialchars($_GET["msg"]);
  60.     //Сохраняем сообщение
  61.     setQuery("INSERT INTO `chat` (`id` ,`name` ,`text` )VALUES (NULL , '".mysql_real_escape_string($name)."', '".mysql_real_escape_string($msg)."');");
  62.   break;
  63. }
  64.  

Как же работает этот скрипт? Сначала, подключается к базе данных. После подключения, смотрим, что запришивает клиент.
Если он запрашивает сообщения, то генерируем сколько сообщений не хватает клиенту. Затем, запрашиваем в безе все необходимые сообщения, добавляем их в массив, генерируем JSON и посылаем все это дело клиенту.

Теперь, у нас есть основа для чата. Все, что нам осталось сделать, так это обновление чата на стороне клиента и добавление новых сообщений в чат. Для всего этого, мы будем использовать Ajax запросы.
Давайте, создадим в файле index.php скрипт для обработки и добавления сообщений.
Добавим между тегов <head>...</head> наш Javascript:
  1. $(function(){
  2.   //Если куки с именем не пустые, тащим имя и заполняем форму с именем
  3.   if($.cookie("name")!=""){$("#t-box input[class='name']").attr("value", $.cookie("name"));}
  4.   //Переменная отвечает за id последнего пришедшего сообщения
  5.   var mid = 0;
  6.   //Функция обновления сообщений чата
  7.   function get_message_chat(){
  8.     //Генерируем Ajax запрос
  9.     $.ajaxSetup({url: "chat.php",global: true,type: "GET",data: "event=get&id="+mid+"&t="+
  10.         (new Date).getTime()});
  11.     //Отправляем запрос
  12.     $.ajax({
  13.       //Если все удачно
  14.       success: function(msg_j){
  15.         //Если есть сообщения в принятых данных
  16.         if(msg_j.length > 2){
  17.           //Парсим JSON
  18.           var obj = JSON.parse(msg_j);
  19.           //Проганяем циклом по всем принятым сообщениям
  20.           for(var i=0; i < obj.length; i ++){
  21.             //Присваиваем переменной ID сообщения
  22.             mid = obj[i].id;
  23.             //Добавляем в чат сообщение
  24.             $("#msg-box ul").append("<li><b>"+obj[i].name+"</b>: "+obj[i].msg+"</li>");
  25.           }
  26.           //Прокручиваем чат до самого конца
  27.           $("#msg-box").scrollTop(2000);
  28.         }
  29.       }
  30.     });
  31.   }
  32.  
  33.   //Первый запрос к серверу. Принимаем сообщения
  34.   get_message_chat();
  35.  
  36.   //Обновляем чат каждые две секунды
  37.   $("#t-box").everyTime(2000, 'refresh', function() {
  38.     get_message_chat();
  39.   });
  40.  
  41.   //Событие отправки формы
  42.   $("#t-box").submit(function() {
  43.     //Запрашиваем имя у юзера.
  44.     if($("#t-box input[class='name']").attr("value") == ""){ alert("Пожалуйста, введите свое имя!")}else{
  45.       //Добавляем в куки имя
  46.       $.cookie("name", $("#t-box input[class='name']").attr("value"));
  47.  
  48.       //Тащим сообщение из формы
  49.       var msg = $("#t-box input[class='msg']").val();
  50.       //Если сообщение не пустое
  51.       if(msg != ""){
  52.         //Чистим форму
  53.         $("#t-box input[class='msg']").attr("value", "");
  54.         //Генерируем Ajax запрос
  55.         $.ajaxSetup({url: "chat.php", type: "GET",data: "event=set&name="+
  56.             $("#t-box input[class='name']").val()+"&msg="+msg});
  57.         //Отправляем запрос
  58.         $.ajax();
  59.       }
  60.     }
  61.     //Возвращаем false, чтобы форма не отправлялась.
  62.     return false;
  63.   });
  64. });

Разберем этот скрипт…
Строка (3). Если в куках есть имя пользователя, то заполняем форму с именем. Для чего это сделано? Если пользователь обновил страничку с чатом или зашел заново на страницу с чатом, то ему не придется вводить свое имя заново.
Строка (7). Функция обновления чата. Чат обновляется не полностью, а присылаются только те сообщения, которых нет в чате.
Строка (9). Генерируем Ajax запрос. Для чего нужно отправлять лишнюю переменную «t=»+(new Date).getTime()? Если не отправить, то некоторые браузеры кэшируют одинаковые Ajax запросы. А нам это не нужно! т.к. не смогут обновляться сообщения. Функция (new Date).getTime() возвращает время в миллисекундах. Таким образом, браузер не кэширует запрос, т.к. при каждой отправке, генерируется разная строка.
Строка (16). Почему именно больше двух символов? Да потому что если все сообщения в чате есть, то сервер присылает не пустую строку, а "[]". т.к. ответ генерируется в JSON.
Строка (37). Запрос новых сообщений раз в две секунды. Мне очень понравился плагин jQuery Timers. С помощью него можно очень гибко сделать повторение определенных действий любое количество раз.

В общем-то, и всё. Вот и готов наш чат. Проверку имени на валидность и смайлы оставляю для домашнего задания.

Посмотреть чат в действии
Полный архив со всем кодом
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.