Как стать автором
Обновить

Простой чат на 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. С помощью него можно очень гибко сделать повторение определенных действий любое количество раз.

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

Посмотреть чат в действии
Полный архив со всем кодом
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.