Создание мини-чата на PHP и jQuery

Создание мини-чата на PHP и jQuery

От автора: В данной обучающей статье мы с вами научимся создавать мини-чат на 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

<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

$(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

<?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

<?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

Источник: http://tutorialzine.com/

Редакция: Команда webformyself.

Курс по программированию на языке PHP

Изучите PHP с нуля до результата!

Смотреть курс

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (5)

  1. Kirill

    Не отправляются сообщения, и вообщеничего не происходит при нажатии на кнопку, что делать?

  2. Дмитрий

    Также не работает. Не помогли также рекомендации и из этой статьи: tutorialzine.com/2015/01/shoutbox-php-jquery/

  3. Александр

    Спасибо за ответ!
    В дополнение к написанному. Проверил в фаербаге: данные отправляются из фрейма методом Get, хотя в форме прописан POST:

    Нашёл ошибку. Ну бывает же так переклинит…
    нужно писать method=»POST», а у меня было написано metod=»post». Так как в коделобстере не разбирает html если он отформатирован в php тегах, то не заметил описки.

    Спасибо! :-)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree