Мощная система для организации чата - Часть 1


Сегодня мы расскажем вам о том, как создать мощный чат. Система будет содержать следующие элементы: функцию регистрации, возможность авторизации, основной чат, поддержку профайлов с аватарами, систему рейтинг (профайлов), возможность отправки личных сообщений, создания частных комнат, возможность осуществления модерации и администрирования. Это будет Ajax-чат (PHP) с возможностью размещения сообщений в базе данных (MySQL). Мы также в процессе разработки задействуем некоторые свойства CSS3/HTML5.

Мощная система для организации чата - Часть 1

Сегодня мы поработаем со следующими элементами: основной код (PHP+SQL) с возможностью авторизации. Все проекты будут структурированы: системные классы будут размещаться в папке «classes», таблицы стилей в «css», а файлы шаблона будут размещены в папке «templates».

Для начала скачайте исходники, и давайте приступать к разработке.

Этап 1 – SQL

Вот SQL-структура таблиц для профайлов и сообщений:

CREATE TABLE `cs_profiles` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `last_name` varchar(255) NOT NULL default '',
  `email` varchar(255) NOT NULL default '',
  `password` varchar(40) NOT NULL default '',
  `salt` varchar(10) NOT NULL default '',
  `status` enum('active','passive') NOT NULL default 'active',
  `role` tinyint(4) unsigned NOT NULL default '1',
  `about` varchar(255) NOT NULL,
  `date_reg` datetime NOT NULL default '0000-00-00 00:00:00',
  `rate` float NOT NULL,
  `rate_count` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

INSERT INTO `cs_profiles` (`name`, `last_name`, `email`, `password`, `salt`, `status`, `role`, `about`, `date_reg`, `rate`, `rate_count`) VALUES
('test user', 'test user last name', 'user@user.com', 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'testing', 'active', 1, 'Few words about test user', '2012-01-14 00:00:00', 0, 0),
('moderator', 'moderator last name', 'moderator@moderator.com', 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'testing', 'active', 4, 'Few words about moderator', '2012-01-14 00:00:00', 0, 0),
('admin', 'admin last name', 'admin@admin.com', 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'testing', 'active', 5, 'Few words about admin', '2012-01-14 00:00:00', 0, 0);

CREATE TABLE `cs_messages` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `sender` int(11) unsigned NOT NULL,
  `recipient` int(11) unsigned NOT NULL default '0',
  `message` VARCHAR(255) NOT NULL,
  `when` TIMESTAMP NOT NULL default CURRENT_TIMESTAMP,
  `room` int(5) unsigned NOT NULL default '0',
  `type` tinyint(1) unsigned NOT NULL default '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Мы добавили в систему 3 профайла. У каждого из них будет своя роль. Мы планируем создать обычных пользователей (1), модераторов (4), и администраторов (5). Вы можете использовать и другие роли (например, с цифрами 2 и 3) для других целей (может быть, платное членство?). Ах да, чуть не упустили – пароль для всех этих пользователей «password». Так что, вы можете войти с логином «test user» с паролем «password» и в качестве остальных («moderator» или «admin») с тем же паролем. Процесс регистрации мы охватим в нашей следующей статьей.

Этап 2 - HTML-код

Давайте рассмотрим основную разметку файла главной страницы:

templates/main_page.html

<!DOCTYPE html>
<html lang="en" >
<head>
    <title>Powerful Chat System</title>
    <link href="css/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <header>
        <h2>Powerful Chat System</h2>
        <a href="http://www.script-tutorials.com/powerful-chat-system/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
    </header>
    <div class="container">
        {form}
    </div>
    <div class="container">
        {chat}
    </div>
</body>
</html>

Довольно просто, не так ли? Теперь, давайте перейдем к следующему файлу шаблона, предназначенному для формы авторизации:

templates/login_form.html

<div class="column">
    <h3>Powerful Chat System Demonstration</h3>
    <p>Our chat will contain next features: registration, main chat, profiles with avatars, ranking system, private messaging, custom rooms, moderation / administration and possible something else (in future).</p>
</div>
<div class="column">
    <form class="login_form" action="index.php" method="post">
        <h3>Log In</h3>
        <label>Username:</label><input type="text" name="username">
        <label>Password:</label><input type="password" name="password">
        <input type="submit" name="LogIn" value="Login">
    </form>
</div>

Следующий шаблон – форма выхода из системы:

logout_form.html

<div class="column">
    <h3>Hello {name}</h3>
    <h3>Your status:</h3>
    <div>{status}</div>
    <h3>Your role:</h3>
    <div>{role}</div>
</div>
<div class="column">
    <a href="index.php?logout">Log Out</a>
</div>

Этап 3 - CSS-код

Данный файл содержит стили для нашего шаблона:

css/main.css

/* page layout */
*{
    margin:0;
    padding:0;
}
body {
    background-color:#eee;
    color:#fff;
    font:14px/1.3 Arial,sans-serif;
}
header {
    background-color:#212121;
    box-shadow: 0 -1px 2px #111111;
    display:block;
    height:70px;
    position:relative;
    width:100%;
    z-index:100;
}
header h2{
    font-size:22px;
    font-weight:normal;
    left:50%;
    margin-left:-400px;
    padding:22px 0;
    position:absolute;
    width:540px;
}
header a.stuts,a.stuts:visited{
    border:none;
    text-decoration:none;
    color:#fcfcfc;
    font-size:14px;
    left:50%;
    line-height:31px;
    margin:23px 0 0 110px;
    position:absolute;
    top:0;
}
header .stuts span {
    font-size:22px;
    font-weight:bold;
    margin-left:5px;
}

/* main styles */
.container {
    background-color:#222;
    color: #bbb;
    margin: 20px auto;
    overflow: hidden;
    padding:20px;
    position: relative;
    width: 800px;
}
.column {
    float:left;
    width:48%;
}
.column:first-child {
    margin-right:4%;
}
.column > * {
    color:#ddd;
    margin-bottom:10px;
}
.column h3 {
    color:#fff;
}
.login_form input,.login_form label {
    display:block;
    margin-bottom:5px;
}
input[type=text],
input[type=password] {
    width:200px;
}
input[type=submit]{
    height:30px;
    margin-top:10px;
    width:72px;
}

Этап 4 - PHP-код

Теперь давайте рассмотрим исходный код наших PHP-файлов:

index.php

<?php

// set error reporting level
if (version_compare(phpversion(), "5.3.0", ">=") == 1)
  error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
  error_reporting(E_ALL & ~E_NOTICE);

require_once('classes/CMySQL.php'); // including service class to work with database
require_once('classes/CLogin.php'); // including service class to work with login processing

// login system init and generation code
$sLoginForm = $GLOBALS['CLogin']->getLoginBox();

$sChat = ($_SESSION['member_name'] && $_SESSION['member_status'] == 'active') ? '<h2>TODO chat</h2>' : '<h2>You have to login before use chat</h2>';

echo strtr(file_get_contents('templates/main_page.html'), array('{form}' => $sLoginForm, '{chat}' => $sChat));

Так как сегодня нам нужен лишь процесс авторизации, наш основной файл (index) будет достаточно невелик. Новые функции будут появляться с последующими руководствами. Вот исходный код нашего процессора, обрабатывающего авторизацию:

classes/CLogin.php

<?php

class CLogin {

    // constructor
    function CLogin() {
        session_start();
    }

    // get login box function
    function getLoginBox() {
        if (isset($_GET['logout'])) { // logout processing
            if (isset($_SESSION['member_name']) && isset($_SESSION['member_pass']))
                $this->performLogout();
        }

        if ($_POST && $_POST['username'] && $_POST['password']) { // login processing
            if ($this->checkLogin($_POST['username'], $_POST['password'], false)) { // successful login
                $this->performLogin($_POST['username'], $_POST['password']);
                header( "Location:{$_SERVER['REQUEST_URI']}" );
                exit;
            } else { // wrong login
                return file_get_contents('templates/login_form.html') . '<h2>Username or Password is incorrect</h2>';
            }
        } else { // in case if we already logged (on refresh page):
            if (isset($_SESSION['member_name']) && $_SESSION['member_name'] && $_SESSION['member_pass']) {
                $aReplaces = array(
                    '{name}' => $_SESSION['member_name'],
                    '{status}' => $_SESSION['member_status'],
                    '{role}' => $_SESSION['member_role'],
                );
                return strtr(file_get_contents('templates/logout_form.html'), $aReplaces);
            }

            // otherwise - draw login form
            return file_get_contents('templates/login_form.html');
        }
    }

    // perform login
    function performLogin($sName, $sPass) {
        $this->performLogout();

        // make variables safe
        $sName = $GLOBALS['MySQL']->escape($sName);

        $aProfile = $GLOBALS['MySQL']->getRow("SELECT * FROM `cs_profiles` WHERE `name`='{$sName}'");
        // $sPassEn = $aProfile['password'];
        $sSalt = $aProfile['salt'];
        $sStatus = $aProfile['status'];
        $sRole = $aProfile['role'];

        $sPass = sha1(md5($sPass) . $sSalt);

        $_SESSION['member_name'] = $sName;
        $_SESSION['member_pass'] = $sPass;
        $_SESSION['member_status'] = $sStatus;
        $_SESSION['member_role'] = $sRole;
    }

    // perform logout
    function performLogout() {
        unset($_SESSION['member_name']);
        unset($_SESSION['member_pass']);
        unset($_SESSION['member_status']);
        unset($_SESSION['member_role']);
    }

    // check login
    function checkLogin($sName, $sPass, $isHash = true) {
        // make variables safe
        $sName = $GLOBALS['MySQL']->escape($sName);
        $sPass = $GLOBALS['MySQL']->escape($sPass);

        $aProfile = $GLOBALS['MySQL']->getRow("SELECT * FROM `cs_profiles` WHERE `name`='{$sName}'");
        $sPassEn = $aProfile['password'];

        if ($sName && $sPass && $sPassEn) {
            if (! $isHash) {
                $sSalt = $aProfile['salt'];
                $sPass = sha1(md5($sPass) . $sSalt);
            }
            return ($sPass == $sPassEn);
        }
        return false;
    }
}

$GLOBALS['CLogin'] = new CLogin();

Надеемся, что вы еще не забыли наше прошлое руководство, посвященное продвинутой системе авторизации. Здесь у нас будет подобная система с использованием шифрования sha1 + md5. Все профайлы будут сохранены в базе данных.

classes/CMySQL.php

Это сервисный класс базы данных. Он доступен в архиве для скачивания. Учтите, что настройки базы данных для нашего проекта находятся именно в этом файле.

Посмотреть демо | Скачать архив
Внимание! У вас нет прав для просмотра скрытого текста.


Завершение

Надеемся, что вы не пропустите наши последующие руководства по созданию чата, и они окажутся интересными и полезными для вас. Если вы хотите поделиться собственными идеями, то это можно сделать посредством поля комментариев, расположенного ниже! Удачи и не забывайте следить за новостями!






Комментарий #1: 27 января 2012 @ 17:32
Мощьная система . доолго я такую искал , хочу протестировать , автору зараннее 5+
Комментарий #2: 27 января 2012 @ 21:18
Не слышал конечно про такое, но учту это , думаю пригодиться в будущем
Комментарий #3: 27 января 2012 @ 23:14
очень интересная статья!!! любопытно где можно найти такой чат в действии
Комментарий #4: 28 января 2012 @ 00:59
Надеемся, что вы не пропустите наши последующие руководства по созданию чата, и они окажутся интересными и полезными для вас.

Ждёмс продолжения =)
Комментарий #5: 28 января 2012 @ 11:39
ITS, продолжение будет. Уже переводится ...


--------------------
Сокращаем ссылки - получаем деньги
Комментарий #6: 28 января 2012 @ 12:52
Design FactoRy, ммм... отлично =)
ну а я пока по тихоньку соберу чат на Denwer`е =)
Комментарий #7: 28 января 2012 @ 22:00
И вправду интересный чат, можно попробовать.
Комментарий #8: 31 января 2012 @ 00:08
Design FactoRy, ужас... то ли я невнимателен, то ли ещё что... а как добавить статью в закладки? belay
Комментарий #9: 31 января 2012 @ 11:34
ITS, вверху возле даты "плюсик" стоит. Вот по нему клик и статья в закладках.


--------------------
Сокращаем ссылки - получаем деньги
Комментарий #10: 31 января 2012 @ 17:20
Design FactoRy, спасибо =) нашёл =)
Комментарий #11: 18 марта 2012 @ 17:52
Отлично. Обязательно повторю.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.