От автора: В данной обучающей статье мы с вами научимся создавать мини-чат на PHP и jQuery, который позволит посетителям вашего сайта оставлять друг другу небольшие комментарии. Сообщения будут храниться на стороне сервера в виде файлов, никакой базы данных, например, MySQL не потребуется. Для облегчения работы мы будем использовать две PHP библиотеки – Flywheel для хранения сообщений в виде файлов в формате JSON и RelativeTime для создания относительных временных меток в удобочитаемом для человека виде. Для установки данных библиотек будет использоваться Composer.
На стороне клиента мы будем использовать обычный jQuery код и библиотеку Emoji One, которая является бесплатной и служит для добавления симпатичных смайликов-эмоджи в веб-приложения. Давайте начинать!
Запускаем мини-чат
Вы можете скачать исходники по вышеприведенной ссылке. В исходном коде содержится много комментариев, и весь код легко читается. Для запуска нужно загрузить исходный код на хостинг или добавить его в папку htdocs сервера Apache, если вы пользуетесь чем-нибудь вроде XAMPP или MAMP. Затем наберите в вашем браузере адрес localhost (или адрес вашего сайта, если вы загрузили исходники на хостинг). Вот несколько моментов, на которые следует обратить внимание:
В zip архивах уже содержатся необходимые зависимости, поэтому вам не нужно устанавливать Composer. Так гораздо проще начать работать с кодом – просто загрузите и используйте!
Убедитесь в том, что директория для хранения данных/сообщений существует и доступна для записи. В противном случае вы увидите сообщения об ошибках в вашем лог-файле, и сообщения не будут сохранены. Возможно, вам потребуется изменить права директории на 777 с помощью команды chmod, если ошибки будут продолжать появляться.
HTML
Давайте начнем с файла index.html. Это обычный HTML5 документ, который включает в себя наши JavaScript библиотеки, скрипты и таблицы стилей. Вот код, относящийся непосредственно к мини-чату:
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<div class="shoutbox"> <h1>Shout box <img src='./assets/img/refresh.png'/></h1> <ul class="shoutbox-content"></ul> <div class="shoutbox-form"> <h2>Write a message <span>×</span></h2> <form action="./publish.php" method="post"> <label for="shoutbox-name">nickname </label> <input type="text" id="shoutbox-name" name="name"/> <label class="shoutbox-comment-label" for="shoutbox-comment">message </label> <textarea id="shoutbox-comment" name="comment" maxlength='240'></textarea> <input type="submit" value="Shout!"/> </form> </div> </div> |
С помощью JavaScript мы поместим опубликованные сообщения внутрь элемента ul. По умолчанию форма скрыта и появляется только при клике на заголовок “Write a message” («Написать сообщение»).
JavaScript
А вот наш файл script.js, который заставляет работать вышеприведенный HTML:
assets/js/script.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
$(function(){ // Сохраняем некоторые элементы в переменные для удобства var refreshButton = $('h1 img'), shoutboxForm = $('.shoutbox-form'), form = shoutboxForm.find('form'), closeForm = shoutboxForm.find('h2 span'), nameElement = form.find('#shoutbox-name'), commentElement = form.find('#shoutbox-comment'), ul = $('ul.shoutbox-content'); // Заменяем :) на смайлики-эмоджи: emojione.ascii = true; // Загружаем комментарии. load(); // При отправке формы, если все заполнено, публикуем сообщение в базе данных var canPostComment = true; form.submit(function(e){ e.preventDefault(); if(!canPostComment) return; var name = nameElement.val().trim(); var comment = commentElement.val().trim(); if(name.length && comment.length && comment.length < 240) { publish(name, comment); // Блокируем публикацию новых сообщений canPostComment = false; // Разрешаем новому комментарию быть опубликованным через 5 секунд setTimeout(function(){ canPostComment = true; }, 5000); } }); // Переключаем видимость формы. shoutboxForm.on('click', 'h2', function(e){ if(form.is(':visible')) { formClose(); } else { formOpen(); } }); // При клике на кнопку REPLY (Ответить) происходит добавление в текстовое поле имени человека, которому вы хотели бы ответить. ul.on('click', '.shoutbox-comment-reply', function(e){ var replyName = $(this).data('name'); formOpen(); commentElement.val('@'+replyName+' ').focus(); }); // При клике на кнопку «Обновить» происходит срабатывание функции load var canReload = true; refreshButton.click(function(){ if(!canReload) return false; load(); canReload = false; // Разрешаем дополнительные перезагрузки через 2 секунды setTimeout(function(){ canReload = true; }, 2000); }); // Автоматически обновляем сообщения каждые 20 секунд setInterval(load,20000); function formOpen(){ if(form.is(':visible')) return; form.slideDown(); closeForm.fadeIn(); } function formClose(){ if(!form.is(':visible')) return; form.slideUp(); closeForm.fadeOut(); } // Сохраняем сообщение в базе данных function publish(name,comment){ $.post('publish.php', {name: name, comment: comment}, function(){ nameElement.val(""); commentElement.val(""); load(); }); } // Получаем последние сообщения function load(){ $.getJSON('./load.php', function(data) { appendComments(data); }); } // Обрабатываем массив с сообщениями в виде HTML function appendComments(data) { ul.empty(); data.forEach(function(d){ ul.append('<li>'+ '<span class="shoutbox-username">' + d.name + '</span>'+ '<p class="shoutbox-comment">' + emojione.toImage(d.text) + '</p>'+ '<div class="shoutbox-comment-details"><span class="shoutbox-comment-reply" data-name="' + d.name + '">REPLY</span>'+ '<span class="shoutbox-comment-ago">' + d.timeAgo + '</span></div>'+ '</li>'); }); } }); |
У библиотеки Emoji One есть версии и для JavaScript и для PHP. В методе appendComments мы используем функцию emojione.toImage(), чтобы сконвертировать все напечатанные смайлы в смайлики-эмоджи. Загляните на этот полезный сайт emoji.codes. Теперь фронтенд готов. Давайте переходить к бэкенду.
PHP
У нас есть два файла – publish.php и load.php. Первый принимает POST запрос, чтобы сохранить сообщения в базе данных, а второй возвращает 20 последних сообщений. Эти файлы не вызываются напрямую посетителями сайта, а только обрабатывают AJAX запросы.
publish.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php // Подключение наших библиотек require 'vendor/autoload.php'; // Настраиваем хранилище данных $dir = __DIR__.'/data'; $config = new \JamesMoss\Flywheel\Config($dir, array( 'formatter' => new \JamesMoss\Flywheel\Formatter\JSON, )); $repo = new \JamesMoss\Flywheel\Repository('shouts', $config); // Сохраняем поступившие данные (сообщения) в хранилище данных if(isset($_POST["name"]) && isset($_POST["comment"])) { $name = htmlspecialchars($_POST["name"]); $name = str_replace(array("\n", "\r"), '', $name); $comment = htmlspecialchars($_POST["comment"]); $comment = str_replace(array("\n", "\r"), '', $comment); // Сохранение нового сообщения $shout = new \JamesMoss\Flywheel\Document(array( 'text' => $comment, 'name' => $name, 'createdAt' => time() )); $repo->store($shout); } |
Здесь мы напрямую используем упомянутую вначале библиотеку Flywheel. Как только она будет настроена, вы можете хранить любые типы данных, которые будут записаны в виде JSON файла в директории data/shouts. Чтение данных сообщений происходит в load.php:
load.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php require 'vendor/autoload.php'; // Если вы хотите удалить старые сообщения, измените значение на true. Мы так сделали для очистки демо-примера. $deleteOldComments = false; // Настройка хранилища данных $dir = __DIR__.'/data'; $config = new \JamesMoss\Flywheel\Config($dir, array( 'formatter' => new \JamesMoss\Flywheel\Formatter\JSON, )); $repo = new \JamesMoss\Flywheel\Repository('shouts', $config); // Удаляем комментарии, опубликованные больше 1 часа назад, если в переменной содержится true. if($deleteOldComments) { $oldShouts = $repo->query() ->where('createdAt', '<', strtotime('-1 hour')) ->execute(); foreach($oldShouts as $old) { $repo->delete($old->id); } } // Отправляем последние 20 сообщений в формате json $shouts = $repo->query() ->orderBy('createdAt ASC') ->limit(20,0) ->execute(); $results = array(); $config = array( 'language' => '\RelativeTime\Languages\English', 'separator' => ', ', 'suffix' => true, 'truncate' => 1, ); $relativeTime = new \RelativeTime\RelativeTime($config); foreach($shouts as $shout) { $shout->timeAgo = $relativeTime->timeAgo($shout->createdAt); $results[] = $shout; } header('Content-type: application/json'); echo json_encode($results); |
Мы добавили код, который удаляет комментарии, опубликованные больше 1 часа назад. Мы используем данную возможность, чтобы не загромождать демо-пример. Вы можете также включить ее при желании. После выбора сообщений мы также высчитываем относительную временную метку в удобочитаемом для человека виде с помощью библиотеки RelativeTime.
Теперь наш мини-чат готов! Вы можете добавить его на ваш веб-сайт, настроить или переделать его так, как вам захочется. Надеемся, что он вам понравился!
Автор: Nick Anastasov
Источник: //tutorialzine.com/
Редакция: Команда webformyself.
Комментарии (12)