Ukrainian (українська мова) translation by Elen (you can also view the original English article)
У цьому уроці ми створюватимемо простий веб-додаток чату за допомогою PHP і jQuery. Утиліта такого типу прекрасно підійде для системи онлайн-підтримки вашого сайту.
Вступ

Додаток чату, який ми сьогодні побудуємо, буде доволі простим. Він буде включати в себе систему входу і виходу, функції стилю AJAX, а також буде пропонувати підтримку декількох користувачів.
Крок 1: HTML розмітка
Ми розпочнемо даний урок зі створення нашого першого файла index.php.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Chat - Customer Module</title> <link type="text/css" rel="stylesheet" href="style.css" /> </head> <div id="wrapper"> <div id="menu"> <p class="welcome">Welcome, <b></b></p> <p class="logout"><a id="exit" href="#">Exit Chat</a></p> <div style="clear:both"></div> </div> <div id="chatbox"></div> <form name="message" action=""> <input name="usermsg" type="text" id="usermsg" size="63" /> <input name="submitmsg" type="submit" id="submitmsg" value="Send" /> </form> </div> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script> <script type="text/javascript"> // jQuery Document $(document).ready(function(){ }); </script> </body> </html>
- Ми почнемо наш html зі звичайного DOCTYPE, html, head і body тегів. В тезі head ми додамо заголовок і посилання на таблицю стилів css (style.css).
- Всередині тега body ми структуруємо наш макет всередині #wrapper div. У нас буде три основних блока: просте меню, вікно чату і поле для введення повідомлення; кожен зі своїм div і id відповідно.
- #menu div буде складатися з двох абзаців. Перший буде привітанням користувача і "попливе" вліво, а другий буде посиланням виходу і "попливе" вправо. Ми також включимо блок div для очистки елементів.
- #chatbox div буде містити лог нашого чату. Ми завантажуватимемо лог із зовнішнього файлу, використовуючи запит ajax jQuery.
- Останнім пунктов в нашому #wrapper div буде форма, яка включатиме поле для введення тексту користувачем і кнопку відправити.
- Ми додамо наші скрипти в останню чергу, щоб сторінка завантажувалась скоріше. Спочатку ми вставимо посилання на Google jQuery CDN, оскільки в даному уроці ми використовуємо бібліотеку jQuery. Наш другий тег скрипта буде там, де ми працюватимемо. Ми завантажимо весь наш код після того, коли буде готовий документ.
Крок 2: створення стилю CSS
Тепер ми додамо трохи css, щоб змусити додаток нашого чату виглядати краще, ніж просто в стилі браузера по замовчуванню. Додамо приведений нижче код в файл style.css.
/* CSS Document */ body { font:12px arial; color: #222; text-align:center; padding:35px; } form, p, span { margin:0; padding:0; } input { font:12px arial; } a { color:#0000FF; text-decoration:none; } a:hover { text-decoration:underline; } #wrapper, #loginform { margin:0 auto; padding-bottom:25px; background:#EBF4FB; width:504px; border:1px solid #ACD8F0; } #loginform { padding-top:18px; } #loginform p { margin: 5px; } #chatbox { text-align:left; margin:0 auto; margin-bottom:25px; padding:10px; background:#fff; height:270px; width:430px; border:1px solid #ACD8F0; overflow:auto; } #usermsg { width:395px; border:1px solid #ACD8F0; } #submit { width: 60px; } .error { color: #ff0000; } #menu { padding:12.5px 25px 12.5px 25px; } .welcome { float:left; } .logout { float:right; } .msgln { margin:0 0 2px 0; }
В приведеному вище css немає нічого особливого, крім того, що деякі id або класи, для яких ми встановлюємо стиль, будуть додані набагато пізніше.

Як бачите, ми закінчили побудову UI чату.
Крок 3: використовуємо РНР, щоб створити форму входу.
Тепер ми реалізуємо просту форму, яка буде запитувати у користувача його ім'я, перш ніж дозволити йому іти далі.
<? session_start(); function loginForm(){ echo' <div id="loginform"> <form action="index.php" method="post"> <p>Please enter your name to continue:</p> <label for="name">Name:</label> <input type="text" name="name" id="name" /> <input type="submit" name="enter" id="enter" value="Enter" /> </form> </div> '; } if(isset($_POST['enter'])){ if($_POST['name'] != ""){ $_SESSION['name'] = stripslashes(htmlspecialchars($_POST['name'])); } else{ echo '<span class="error">Please type in a name</span>'; } } ?>
Функція loginForm(), яку ми створили, складається з простої форми входу, яка запитує у користувача його ім'я. Далі ми використовуємо конструкцію if і else, щоб перевірити, чи користувач ввів ім'я. Якщо він/вона ввели ім'я, ми встановлюємо його як $_SESSION['name']. Так як ми використовуємо сесію на основі cookie, щоб зберегти ім'я, ми повинні викликати session_start() перед тим, як виводити що-небудь в браузер.
Є одна річ, на яку ви напевне захочете звернути увагу - це те, що ми використовували функцію htmlspecialchars(), яка конвертує спеціальні символи в HTML, тим самим захищаючи ім'я змінної, щоб воно не стало жертвою Cross-site scripting (XSS). Ми також додамо цю функцію пізніше до текстової змінної, яка буде опублікована в лозі чата.
Відображення форми входу
Для того, щоб показати форму входу в випадку, якщо користувач не ввійшов в систему, і відповідно сесія також не була створена, ми використаємо іншу конструкцію if і else навколо #wrapper div і тегів скрипта в оригінальному коді. В іншому випадку, якщо користувач ввійшов в систему і створив сесію, цей код приховає форму входу і покаже вікно чату.
<?php if(!isset($_SESSION['name'])){ loginForm(); } else{ ?> <div id="wrapper"> <div id="menu"> <p class="welcome">Welcome, <b><?php echo $_SESSION['name']; ?></b></p> <p class="logout"><a id="exit" href="#">Exit Chat</a></p> <div style="clear:both"></div> </div> <div id="chatbox"></div> <form name="message" action=""> <input name="usermsg" type="text" id="usermsg" size="63" /> <input name="submitmsg" type="submit" id="submitmsg" value="Send" /> </form> </div> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script> <script type="text/javascript"> // jQuery Document $(document).ready(function(){ }); </script> <?php } ?>

Меню привітання і меню входу
Ми ще не закінчили створювати систему входу для даного додатку чата. Нам ще потрібно дати користувачу можливість вийти з системи і закінчити сесію чата. Як ви пам'ятаєте, наша оригінальна розмітка HTML включає просте меню. Давайте повернемось назад і додамо деякий РНР код, який надасть меню більше функціональності.
Перш за все, давайте додамо в повідомлення привітання ім'я користувача. Для цього виведемо сесію імені користувача.
<p class="welcome">Welcome, <b><?php echo $_SESSION['name']; ?></b></p>

Для того, щоб дозволити користувачу вийти із системи і завершити сесію, ми "стрибнемо вище голови" і коротко використаємо jQuery.
<script type="text/javascript"> // jQuery Document $(document).ready(function(){ //If user wants to end session $("#exit").click(function(){ var exit = confirm("Are you sure you want to end the session?"); if(exit==true){window.location = 'index.php?logout=true';} }); }); </script>
Приведений вище код jquery просто показує повідомлення підтвердження, якщо користувач натиснув посилання #exit. Якщо користувач підтверджує вихід, тим самим вирішивши закінчити сесію, ми перенаправимо його в index.php?logout=true. Це просто створює змінну з іменем logout зі значенням true. Нам потрібно перехопити цю змінну за допомогою РНР.

if(isset($_GET['logout'])){ //Simple exit message $fp = fopen("log.html", 'a'); fwrite($fp, "<div class='msgln'><i>User ". $_SESSION['name'] ." has left the chat session.</i><br></div>"); fclose($fp); session_destroy(); header("Location: index.php"); //Redirect the user }
Тепер ми побачимо, чи існує змінна get 'logout', використовуючи функцію isset(). Якщо змінна була передана через url, наприклад, як посилання, яке згадувалось вище, то ми переходимо до завершення сесії користувача з поточним ім'ям.
Перед ліквідацією сесії користувача з поточним ім'ям за допомогою функції session_destroy(), ми хочемо виводити просте повідомлення про вихід в лог чата. В ньому буде сказано, що користувач покинув сесію чата. Ми зробимо це, використовуючи функцію fopen(), fwrite() і fclose() для маніпуляції нашим файлом log.html, який, як ми побачимо пізніше, буде створено в якості лога нашого чата. Будь-ласка, зверніть увагу, що ми додали клас 'msgln' до div. Ми вже визначили стиль css для цього div.
Зробивши це, ми ліквідовуємо сесію і перенаправляємо користувача на ту сторінку, де з'явиться форма входу в систему.
Крок 4: підтримка введення даних користувачем
Після того, як користувач підтвердив свої дії в нашій формі, нам потрібно захоплювати ведення даних і записувати їх в лог чата. Для того, щоб це зробити, ми повинні використовувати jQuery і PHP, щоб працювати синхронно на стороні сервера і клієнта.
jQuery
Практично все, що ми збираємось робити з jQuery для обробки наших даних, буде зосереджуватися навколо запиту на jQuery post.
//If user submits the form $("#submitmsg").click(function(){ var clientmsg = $("#usermsg").val(); $.post("post.php", {text: clientmsg}); $("#usermsg").attr("value", ""); return false; });
- Перед тим, як ми почнемо щось робити, нам потрібно захопити введення користувача або те, що він написав в потік вводу #submitmsg. Цього можна досягнути за допомогою функції val(), яка бере значення, встановлене в полі форми. Тепер ми зберігаємо це значення в змінну clientmsg.
- Ось тут і настає найважливіша частина: запит jQuery post. Він відправляє POST-запит в файл post.php, який ми створимо за мить. Він надсилає введення клієнта або те, що було збережено в змінну clientmsg.
- Наостанок, ми очищаємо введення #usermsg, роблячи пустим значення атрибута.
Будь-ласка, зверніть увагу, що код, вказаний вище, піде в наш тег скрипта, де ми розмістили код виходу з системи jQuery.
PHP - post.php
На даний момент ми маємо дані POST, які відправляються в файл post.php щоразу, коли користувач відправляє форму і нове повідомлення. Наше завдання тепер - захопити ці дані і записати їх в лог нашого чата.
<? session_start(); if(isset($_SESSION['name'])){ $text = $_POST['text']; $fp = fopen("log.html", 'a'); fwrite($fp, "<div class='msgln'>(".date("g:i A").") <b>".$_SESSION['name']."</b>: ".stripslashes(htmlspecialchars($text))."<br></div>"); fclose($fp); } ?>
- Перш ніж ми щось зробимо, ми повинні почати файл post.php з функцією session_start(), оскільки ми використовуватимемо сесію по імені користувача в даному файлі.
- Використовуючи логічну isset, ми перевіримо, чи існує сесія для 'name' перед тим, як робити щось далі.
- Тепер ми захопимо дані POST, які jQuery відправив в цей файл. Ми збережемо ці дані в змінну $text.
- Ці дані, як і взагалі всі дані, які вводяться користувачем, будуть зберігатися в файлі log.html. Для цього відкриємо файл в режимі 'a' функції fopen, який, відповідно php.net, відкриває файл тільки для запису, розміщує вказівник файла в його кінець. Якщо файл не існує - спробуємо створити його. Далі ми запишемо наше повідомлення в файл, використовуючи функцію fwrite().
- Повідомлення, яке ми будемо записувати, розміщуватиметься всередині .msgln div. Він міститиме дату і час, згенеровані функцією date(), сесію імені користувача і текст, який також буде заключений функцією htmlspecialchars(), щоб уникнути XSS.
І на кінець ми закриваємо наш файл за допомогою fclose().
Крок 5: відображення вмісту Chat Log (log.html).
Все, що розмістив користувач, оброблено і опубліковано за допомогою jQuery; воно записано в лог чата за допомогою РНР. Єдине, що залишилось зробити, це показати оновлений лог чата користувачу.
Щоб зекономити трохи часу, ми попередньо завантажимо лог чата в #chatbox div так, ніби він містив би якийсь контент.
<div id="chatbox"><?php if(file_exists("log.html") && filesize("log.html") > 0){ $handle = fopen("log.html", "r"); $contents = fread($handle, filesize("log.html")); fclose($handle); echo $contents; } ?></div>
Ми використовуємо процедуру схожу на ту, що ми використовували в файлі post.php, але на цей раз ми тільки читаємо і виводимо вміст файла.
Запит jQuery.ajax
Запит ajax - це ядро всього, що ми робимо. Цей запит дозволяє нам не тільки відправляти і приймати дані через форму без оновлення сторінки, але також і дозволяє нам обробляти дані, на які приходить запит.
//Load the file containing the chat log function loadLog(){ $.ajax({ url: "log.html", cache: false, success: function(html){ $("#chatbox").html(html); //Insert chat log into the #chatbox div }, }); }
Ми загорнемо наш запит ajax в функцію. За мить ви зрозумієте, чому. Як ви можете бачити вище, ми використали тільки три із об'єктів запиту ajax jQuery.
- url: рядок URL для запиту. Ми використовуємо ім'я файла лога нашого чата log.html.
- cache: це попередить кешування нашого файла. Також це забезпечить нам те, що завжди, коли ми відправляємо запит, ми будемо мати оновлений лог чата.
- sucess: це дозволить нам прикріпити функцію, яка передасть дані, які ми запитуємо.
Як ви бачите, потім ми переміщуємо дані, які ми запитуємо (html), в #chatbox div.
Автоскролинг
Можливо в інших додатках чатів ви бачили, що їх вміст автоматично прокручується вниз, якщо контейнер лога чата (#chatbox) переповнюється. Ми реалізуємо просту і схожу функцію, яка порівнюватиме висоту полоски прокрутки контейнера до і після того, як ми виконаємо запит ajax. Якщо висота полоски прокрутки стала більшою після запиту, ми використаємо ефект анімації jQuery, щоб прокрутити #chatbox div.
//Load the file containing the chat log function loadLog(){ var oldscrollHeight = $("#chatbox").attr("scrollHeight") - 20; //Scroll height before the request $.ajax({ url: "log.html", cache: false, success: function(html){ $("#chatbox").html(html); //Insert chat log into the #chatbox div //Auto-scroll var newscrollHeight = $("#chatbox").attr("scrollHeight") - 20; //Scroll height after the request if(newscrollHeight > oldscrollHeight){ $("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div } }, }); }
- Спочатку ми збережемо висоту полоски прокрутки #chatbox div в змінну oldscrollHeight перед виконанням запиту.
- Після того, як наш запит поверне успіх, ми збережемо висоту полоски прокрутки #chatbox в змінну newscrollHeight.
- Потім ми порівняємо висоту полоски прокрутки в обох змінних, використовуючи конструкцію if. Якщо newscrollHeight більше, ніж oldscrollHeight, ми використовуємо ефект анімації, щоб прокрутити #chatbox div.
Постійне оновлення лога чата
Тепер може виникнути питання, як часто ми будемо постійно оновлювати наші дані, передані між користувачами. Або, іншими словами, як ми зможемо постійно відправляти запити для оновлення даних?
setInterval (loadLog, 2500); //Reload file every 2500 ms or x ms if you wish to change the second parameter
Відповідь на наше питання знаходиться в функції setInterval. Дана функція буде запускати нашу функцію loadLog() кожні 2,5 секунди, яка буде відправляти запит на оновлення файла і здійснювати автоскролинг лога.

Ось і все.
Ми завершили! Я сподіваюсь, що ви вивчили, як працює базова система чату і, якщо у вас є якісь побажання, я з радістю їх вислухаю. Це максимально проста система чата, яку ви можете створити як додаток. Ви можете відійти від цього і побудувати безліч кімнат чатів, додати адмінку, емотикони і т.д. Можливостей - до небес.
Нижче приведу декілька посилань, які ви можливо захочете переглянути, якщо обмірковуєте розширити цей додаток чата:
- Secure Your Forms With Form Keys - попередження XSS (Cross-site scripting) і підробок крос-сайтових запитів.
- Submit A Form Without Page Refresh using jQuery - розширте наш запит ajax.
- How to Make AJAX Requests With Raw Javascript - дізнайтесь, як працюють запити "за кулісами" чистого javascript.

- Слідкуйте за нами в Twitter або підпишіться на NETTUTS RSS Feed для щоденних навчальних матеріалів і статей по веб-розробці.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post