Чат на PHP

Здравствуйте, уважаемые web-мастера! Я уверен, что вы хотите, чтобы ваш сайт активно посещался, чтобы посетителям был интересен материал, размещенный на вашем сайте, и чтобы они возвращались вновь и вновь. Скорее всего, у вас на сайте уже работает форум и гостевая книга. Но чего-то всё же не хватает… Чего? Чата! Чата, в котором можно было бы пообщаться и из-за которого посетители будут возвращаться снова и снова.

Что для этого нужно?

Так в чём же дело? Давайте напишем свой собственный чат, который будет отвечать всем вашим требованиям, будет быстрым и компактным.

Теперь давайте определимся, что должен уметь наш чат:

Теперь определимся, какие технологии мы будем использовать при разработке чата. Писать будем на PHP, а для регистрации пользователей информацию о них будем хранить в базе данных MySQL. Сам текст болталки (болталкой назовем информацию, которой обмениваются посетители) будет находиться в текстовом файле.

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

Теперь я уточню ещё несколько деталей, которые необходимо обсудить ещё до написания кода.

В текстовом файле chat.txt (в нём будет храниться наша «болталка») должно находиться не более 20 последних сообщений (для уменьшения трафика и ускорения загрузки чата).

При входе в чат посетитель должен будет ввести логин (он же ник) и пароль, причём если такой логин уже хранится в нашей таблице базы данных, то скрипт должен проверить, верен ли пароль. Если верен, то перенаправить посетителя в чат, а если неверен – вернуть на главную страницу для повторного ввода логина и пароля и сообщить ему, что пароль неверен.

Если же такого логина в таблице нет, то нужно зарегистрировать посетителя, т.е. добавить в таблицу данные о нём (логин и пароль). Но отдельной страницы для регистрации нового посетителя (далее будем называть посетителей «пользователями») делать не нужно, чтобы не отпугнуть значительную часть посетителей.

Кроме того, если вы планируете создать небольшой чат, к примеру, для общения с друзьями, то было бы неплохо записывать всё, что произносилось в чате, в отдельный файл (назовем его history.txt). В дальнейшем можно будет произвести некоторые действия над этим файлом (например, каждый день в 12:00 отсылать содержимое этого файла вам на e-mail, а после этого очищать его). Но это будем делать после того, как наш чат уже будет работать.

Какие файлы нужны для создания чата?

Теперь определимся, какие файлы нужно создать для работы чата. Ниже приведен полный список файлов чата с описанием, для чего нужен тот или иной файл.

А теперь нужно упомянуть один момент, без объяснения которого никак нельзя обойтись.

Что еще?

Как обычно, люди уходят из чата? Правильно, редко кто нажимает на кнопку выход, обычно просто закрывают окно с чатом. Нам нужно отслеживать эти моменты, чтобы вовремя убрать ушедших пользователей из списка находящихся в чате. Допустим, у человека что-то случилось и он обновляет страницу. В обоих этих случаях происходит событие Unload, которое можно отследить при помощи JavaScript-обработчика onUnload. О данной проблеме я подробнее расскажу при описании работы файлов chat.inc.php, send.php и del.php.

Если вы хотите посмотреть, как работает описанный в статье чат, можете зайти на chat.micro.org.ua и убедиться, что все описанное в этой статье работает.

Начинаем работу

Теперь, когда вроде бы все вопросы выяснены, можно приступать к непосредственному набору кода. В начале я буду писать полный код файла, а потом буду подробно описывать его действия. Перед этим создайте пустые файлы chat.txt и history.txt.

Кроме того, в тот же каталог, где у вас находится чат, положите 7 gif-файлов — это наши смайлики. Если у вас нет смайликов, их можно взять с chat.micro.org.ua.

Также создайте таблицу стилей style.css для дальнейшего оформления чата. Создайте в ней два класса: normal и title.

Нам также нужен логотип чата. У меня логотипом является слово «MICRO», написанное на синем фоне золотыми буквами высотой 55 и шириной 195 пикселей. Этот момент оставляю на ваше усмотрение.

Открывайте свой любимый РНР-редактор и начинайте. Я начну с второстепенных файлов, чтобы потом не отвлекаться на их описание.

Chat_users.sql

Для начала нужно создать таблицу «chat_users» в базе данных. Итак, вот ее код:

CREATE TABLE chat_users (
  id int(10) NOT NULL auto_increment,
  login text NOT NULL,
  password text NOT NULL,
  privat text NOT NULL,
  active tinyint(2) NOT NULL default '0',
  PRIMARY KEY (id)
) TYPE=MyISAM;

Мы создали таблицу, в которой находится пять столбцов:

  1. id – идентификатор пользователя
  2. login – логин (ник) пользователя
  3. password – пароль пользователя
  4. privat – это задел на будущее, когда мы будем работать над «приватом»
  5. active – тут будет храниться лишь одна цифра: 1 – если пользователь в данный момент находится в чате, и 0, если пользователь в данный момент не в чате.

Тут нет ничего сложного.

Incuder.php
<?php
$myserver="";
//Обычно это - localhost
$mylogin="micro"; // Ваш логин
$mypassword=""; //Ваш пароль
?>

Это – ваши данные для подключения к базе данных.

Logo.html
<HTML>
<HEAD>
    <META NAME="Author" CONTENT="ILYA BARKOV">
</HEAD>
<BODY TOPMARGIN=0 LEFTMARGIN=0 RIGHTMARGIN=0 MARGINHEIGHT=0 MARGINWIDTH=0 BGCOLOR="#8caae6">
    <CENTER>
        <IMG SRC="logo_chat.jpg" ALT="Micro Chat" WIDTH="195">
    </CENTER>
</BODY>
</HTML>

Тут и пояснять особо нечего. Мы создаем HTML-документ, вставляем в него изображение-логотип чата и прижимаем его к рамам страницы при помощи строки «TOPMARGIN=0 LEFTMARGIN=0 RIGHTMARGIN=0 MARGINHEIGHT=0 MARGINWIDTH=0».

Ну, а теперь приступим к основным файлам чата.

Index.php
<HTML>
    <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html">
        <TITLE>Чат на MICRO.ORG.UA</TITLE>
        <LINK HREF="style.css" REL="stylesheet" TYPE="text/css">
    </HEAD>
    <BODY LINK="blue" ALINK="blue" VLINK="blue">
        <SCRIPT LANGUAGE="JavaScript">
            <!--
            function proverka(f) {
                var login = f.login.value;
                var password = f.password.value;
                if (login == '') {
                    alert('Введите свое имя или ник! Вы не можете зайти в чат без имени.\nMICRO');
                    f.login.focus();
                    return false;
                }
                if (password == '') {
                    alert('Введите свой пароль! Это значение не должно оставаться пустым - для защиты вашего же пользователя.\nMICRO');
                    f.password.focus();
                    return false;
                }
                if (login.toLowerCase() == password.toLowerCase()) {
                    alert('По правилам чата логин и пароль должны не совпадать друг с другом!\nMICRO');
                    return false;
                }
            }
            -->
        </SCRIPT>
        <FORM ACTION="chat.php" METHOD="POST" ONSUBMIT="return proverka(this);" NAME="entry">
            <TABLE HEIGHT="100%" VALIGN="middle" WIDTH="100%">
                <TR>
                    <TD>
                        <TABLE BORDER="1" CELLPADDING="4" CELLSPACING="0" WIDTH="100%" BGCOLOR="#FFFFFF" BORDERCOLOR="#000000" RULES="all" HEIGHT="300">
                            <TR BGCOLOR="lavender">
                                <TH COLSPAN="2" CLASS="title">Добро пожаловать в Чат Микропортала</TH>
                            </TR>
                            <TR>
                                <TD>Ваше имя (или ник):</TD>
                                <TD><INPUT TYPE="text" NAME="login" SIZE="40" VALUE=""></TD>
                            </TR>
                            <TR>
                                <TD>Пароль (должен отличаться от ника):</TD>
                                <TD><INPUT TYPE="password" NAME="password" SIZE="40" VALUE=""></TD>
                            </TR>
                            <TR>
                                <TD COLSPAN="2"><INPUT TYPE="submit" VALUE="Войти в чат" STYLE="width: 300px;"></TD>
                            </TR>
                            <TR>
                                <TD COLSPAN="2" BGCOLOR="lavender"><FONT COLOR="#6766f1"><B>Примечание:</B></FONT> если Вы заходите сюда в первый раз, то введите свой пароль, и он будет запомнен системой</TD>
                            </TR>
                        </TABLE>
                    </TD>
                </TR>
            </TABLE>
        </FORM>
    </BODY>
</HTML>

Пока что в этом документе нет РНР-дескрипторов, но потом, при расширении функциональности чата, здесь будут выводиться некоторые данные о работе чата.

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

Данные из формы передаются в файл chat.php. Его то мы сейчас и рассмотрим.

Chat.php
<?php
error_reporting(0);
include("includer.php");
$login = $_POST['login'];
$password = $_POST['password'];

if (($login != '') && ($password != '')) {
    echo "<TITLE>Чат на MICRO.ORG.UA - " . strtoupper($login) . "</TITLE>";
    $db = mysql_connect($myserver, $mylogin, $mypassword);
    mysql_select_db("micro");

    // Проверяем, зарегистрирован ли такой ник в чате
    $sql = "SELECT * FROM `chat_users` WHERE `login`='" . $login . "'";
    $result = mysql_query($sql);
    $num_results = mysql_num_rows($result);

    // Если человека с таким ником нет в чате, то регистрируем его и делаем активным
    if (($num_results == '') || ($num_results == 0)) {
        $sql = "INSERT INTO `chat_users` VALUES ('', '" . $login . "','" . $password . "','','1')";
        $result = mysql_query($sql);
        include("chat.inc.php");
    }
    // Иначе проверяем: если он ввел верный пароль - он входит в чат, иначе переходит на главную страницу
    else {
        $sql = "SELECT * FROM `chat_users` WHERE `login`='" . $login . "' and `password`='" . $password . "'";
        $result = mysql_query($sql);
        $num_results = mysql_num_rows($result);

        if (($num_results == '') || ($num_results == 0)) {
            echo '<SCRIPT LANGUAGE="JavaScript">
            <!--
            alert(\'Вы ввели неверный пароль. Если Вы - обладатель этого ника, то попробуйте ввести еще раз, а если нет - то зайдите под другим ником.\nMICRO\');
            location.href="index.php";
            //-->
            </SCRIPT>';
        } else {
            $sql = "SELECT * FROM `chat_users` WHERE `login`='" . $login . "'";
            $result = mysql_query($sql);
            $num_results = mysql_num_rows($result);
            $row = mysql_fetch_array($result);
            $id = $row["id"];
            $sql = "DELETE FROM `chat_users` WHERE `id`=" . $id;
            $result = mysql_query($sql);
            $sql = "INSERT INTO `chat_users` VALUES ('" . $id . "', '" . $login . "','" . $password . "','','1')";
            $result = mysql_query($sql);
            include("chat.inc.php");
        }
    }
} else {
    Header("Location:index.php");
}
?>

Что мы делаем в этом файле? Первым делом выставляем подавление ошибок (error_reporting(0)) – чтобы ни случилось, посетители не должны видеть сообщения об ошибках. Далее подключаем файл includer.php с данными для подключения к базе данных. Выбираем из массива POST значения логина и пароля и, если они не пусты, продолжаем работу сценария. Потом проверяем, есть ли у нас в таблице chat_users пользователь с таким логином. Если нет, то заносим логин и пароль в таблицу – таким образом проходит регистрация. Если же такой логин уже есть в таблице, то проверяем, совпадает ли пароль, введенный посетителем, с паролем, находящимся в таблице. Если нет, то создаем JavaScript-код, содержащий сообщение о том, что пароль неверен, и перебрасываем его на страницу index.php. Если же все нормально, то выдаем посетителю файл chat.inc.php. Кроме того, производим некоторые манипуляции над таблицей: заносим в поле «active» этого посетителя число 1, т.е. делаем его активным.

Chat.inc.php
<FRAMESET COLS="*, 50, 200" BORDER="1" FRAMEBORDER="1" FRAMESPACING="0" ONUNLOAD="window.location.href='del.php?login=<?=$login;?>'">
    <FRAMESET ROWS="*, 65">
        <FRAME NAME="text" SRC="text.php?login=<?=$login;?>">
        <FRAME NAME="send" SRC="send.php?login=<?=$login;?>">
    </FRAMESET>
    <FRAME NAME="smiles" SRC="smiles.html">
    <FRAMESET ROWS="55, *">
        <FRAME NAME="logo" SRC="logo.html" NORESIZE>
        <FRAME NAME="users" SRC="users.php?login=<?=$login;?>">
    </FRAMESET>
</FRAMESET>

В этом файле содержится набор фреймов, в которых содержатся PHP-файлы.

Когда срабатывает событие ONUNLOAD, обработка событий передается файлу del.php. Подробнее о работе этого файла – в конце статьи.

Обратите внимание – в каждый из документов, находящихся во фреймах (исключение – logo.html и smiles.html), мы передаем с помощью строки запроса логин посетителя. Зачем это нужно? Об этом я расскажу позднее.

Text.php
<HTML>
<HEAD>
    <META CONTENT="5; URL=text.php" HTTP-EQUIV="Refresh">
</HEAD>
<BODY ONLOAD="scroll(0,100)" LINK="blue" ALINK="blue" VLINK="blue">
    <FONT SIZE="3" FACE="Georgia">
        <?php
        error_reporting(0);

        // Если в чате больше 20 строк, то убираем самые ранние, чтобы в окне оставалось не более 20 строк

        $file = file("chat.txt");
        $count = count($file);

        $num = 20;

        if ($count > $num) {
            for ($i = ($count - $num); $i < $count; $i++) {
                $str = $str . $file[$i];
                $str = str_replace("\r\n", "\n", $str);
            }

            $fp = fopen("chat.txt", "w");
            fwrite($fp, $str);
        }

        $file = file("chat.txt");
        $count = count($file);

        for ($i = 0; $i < $count; $i++) {
            echo $file[$i] . "<BR>";
        }
        ?>
    </FONT>
</BODY>
</HTML>

На этот документ стоит обратить особое внимание.

При помощи строки "<META CONTENT='5; URL=text.php' HTTP-EQUIV='Refresh'>" мы выставляем частоту обновления файла – пять секунд. По моим наблюдениям, 5 секунд для нашего чата – оптимальная частота обновления. Файл, который будет каждый раз считываться, состоит всего лишь из 20 строк, поэтому чем быстрее обновляется text.php, тем для нас лучше.

Естественно, выставляем подавление сообщений об ошибках.

Далее при помощи функции file() мы считываем информацию из файла chat.txt и выводим информацию на экран, предварительно заменяя символы "\n" (перенос строки) на "<BR>".

Обратите внимание на строки:

$num=20;
if ($count > $num)
{
    for ($i = ($count - $num); $i < $count; $i++)
    {
        $str = $str . $file[$i];
        $str = ereg_replace("\r\n", "\n", $str);
    }
    $fp = fopen("chat.txt", "w");
    fwrite($fp, $str);
}

С помощью этого кода мы оставляем в "болталке" лишь последние 20 строк. Эта проверка выполняется после того, как количество строк в файле chat.txt превысит 20.

И еще один немаловажный момент. Наш документ должен прокручиваться вниз, чтобы пользователи видели самые последние реплики. Этого мы достигаем, применяя в теге <BODY> обработчик события Load: <BODY ONLOAD='scroll(0,100)'>

Smiles.html
<HTML>
<HEAD>
    <META NAME="Generator" CONTENT="Macro HTML 1.40 beta">
    <SCRIPT LANGUAGE="JavaScript">
        <!--
        function insertsmile(dat) {
            window.parent.send.sendform.message.focus();
            window.parent.send.sendform.message.value += dat + ' ';
        }
        -->
    </SCRIPT>
</HEAD>
<BODY BGCOLOR="#8caae6">
    <CENTER>
        <A HREF="javascript:insertsmile('<1>')"><IMG SRC="1.gif" BORDER="0"></A>
        <A HREF="javascript:insertsmile('<2>')"><IMG SRC="2.gif" BORDER="0"></A>
        <A HREF="javascript:insertsmile('<3>')"><IMG SRC="3.gif" BORDER="0"></A>
        <A HREF="javascript:insertsmile('<4>')"><IMG SRC="4.gif" BORDER="0"></A>
        <A HREF="javascript:insertsmile('<5>')"><IMG SRC="5.gif" BORDER="0"></A>
    </CENTER>
</BODY>
</HTML>

При помощи JavaScript мы вставляем в строку реплики, находящуюся в файле send.php, код смайлика. Позже, в файле add.php, мы вместо кода <5> вставим <IMG SRC="5.gif">, и у пользователей на экран выведется нормальный смайлик.

Send.php
<HTML>
<HEAD>
</HEAD>
<BODY BGCOLOR="#8caae6">
    <TABLE WIDTH="100%" HEIGHT="100%" CELLPADDING="0" CELLSPACING="0">
        <TR VALIGN="middle">
            <TD WIDTH="80%">
                <FORM NAME="sendform" ACTION="add.php" METHOD="post">
                    <?
                    error_reporting(0);
                    $login=$_GET['login'];
                    ?>
                    <INPUT TYPE="hidden" VALUE="<?=$login;?>" NAME="login">
                    <INPUT TYPE="text" NAME="who" STYLE="width:15%; border-width:1px; border-color:black">
                    <INPUT TYPE="text" NAME="message" STYLE="width:75%; border-width:1px; border-color:black">
                </TD>
                <TD WIDTH="15%">
                    <INPUT TYPE="submit" VALUE="Сказать" STYLE="border-width:1px; border-color:black">
                </TD>
                </FORM>
                <FORM ACTION="del.php" METHOD="get" NAME="closeform" TARGET="_parent">
                    <TD WIDTH="20%">
                        <INPUT TYPE="hidden" NAME="login" VALUE="<?=$login;?>">
                        <INPUT TYPE="submit" VALUE="Выход" STYLE="border-width:1px; border-color:black">
                    </TD>
                </FORM>
            </TR>
    </TABLE>
</BODY>
</HTML>

В этом файле находятся две формы. Первая из них содержит два текстовых поля (одно для ввода имени собеседника, другое — для ввода реплики) и кнопку "Сказать", которая передает данные этой формы в файл add.php. Вторая включает в себя лишь одну кнопку "Выход", нажатие на которую активизирует файл del.php и выводит посетителя из чата. Конечно, вряд ли кто-то воспользуется этой кнопкой, но все же…

Кроме того, обе формы передают в файлы-обработчики логин пользователя.

Users.php
<HTML>
<HEAD>
    <?php
    error_reporting(0);
    include("includer.php");
    $login = $_GET['login'];
    ?>
    <META CONTENT="10; URL=users.php?login=<?=$login;?>" HTTP-EQUIV="Refresh">
    <SCRIPT LANGUAGE="JavaScript">
        <!--
        function netsend(dat)
        {
            window.parent.send.sendform.who.value += dat;
            window.parent.send.sendform.message.focus();
        }
        -->
    </SCRIPT>
</HEAD>
<BODY LINK="blue" ALINK="blue" VLINK="blue" TOPMARGIN="0" LEFTMARGIN="0" MARGINWIDTH="0" MARGINHEIGHT="0" RIGHTMARGIN="0">
    <FONT FACE="georgia" SIZE="3" COLOR="black">
        <TABLE WIDTH="100%">
            <TR>
                <TD WIDTH="100%">
                    <FONT COLOR="#008080" FACE="Georgia" SIZE="3"><B>Сейчас в чате:</B></FONT>
                </TD>
            </TR>
            <?php
            $db = mysql_connect($myserver, $mylogin, $mypassword);
            mysql_select_db("micro");
            $sql = "SELECT * FROM `chat_users` WHERE `active`=1";
            $result = mysql_query($sql);
            $num_results = mysql_num_rows($result);
            for ($i = 0; $i < $num_results; $i++)
            {
                $row = mysql_fetch_array($result);
                echo "<TR><TD>" . ($i + 1) . ". <A HREF='javascript:netsend(\"" . stripslashes($row['login']) . "\")'>" . stripslashes($row['login']) . "</A></TD></TR>";
            }
            ?>
            <TR>
                <TD WIDTH="100%">
                    <FONT COLOR="#008080" FACE="Georgia" SIZE="3"><B>Рекомендую:</B></FONT>
                </TD>
            </TR>
            <TR>
                <TD WIDTH="100%" ALIGN="left">
                    1. <A HREF="http://www.micro.org.ua" TARGET="_blank">Микропортал</A>
                    2. <A HREF="http://www.micro.org.ua/forum/" TARGET="_blank">Наши форумы</A>
                    3. <A HREF="http://www.micro.org.ua/yslygi/" TARGET="_blank">Услуги</A>
                </TD>
            </TR>
            <TR>
                <TD WIDTH="100%">
                    <FONT COLOR="#008080" FACE="Georgia" SIZE="3"><B>Правила чата:</B></FONT>
                </TD>
            </TR>
            <TR>
                <TD WIDTH="100%" ALIGN="left">
                    <B>1.</B> Admin всегда прав.
                    <B>2.</B> Если Admin неправ, смотри пункт 1.
                    <B>3.</B> Если уходите - воспользуйтесь кнопкой "Выход"
                    <B>4.</B> За флуд и ругательства вы можете быть удалены из чата
                </TD>
            </TR>
        </TABLE>
    </FONT>
</BODY>
</HTML>

При помощи этого файла мы выводим на экран список активных посетителей (т.е. тех, у которых в данный момент в поле "active" стоит значение 1). Этот файл обновляется каждые 10 секунд.

Кроме того, мы выводим в этом файле список сайтов, которые рекомендуем посетить пользователям (авось, кто-то из них и кликнет по ссылке, которая, кстати, откроется в новом окне), а также правила чата. Я не стал слишком перегружать посетителей правилами: не ругаться, не флудить, слушаться Admin’а. Кстати, об Admin’e – в следующей статье я расскажу вам, что это за Admin, и что мы будем с его помощью делать.

Add.php
<?php
error_reporting(0);
$file = fopen("chat.txt", "a");
$filehis = fopen("history.txt", "a");
for ($i = 1; $i < 8; $i++) {
    $message = ereg_replace("<" . $i . ">", "<img src='" . $i . ".gif'>", $message);
}
// С помощью этих строк мы выделяем из реплики адреса сайтов и e-mail`ы.
$message = eregi_replace('([[:space:]()[{}])(http://.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1<a href="http://\\2" target="_blank">\\2</a>', $message);
$message = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1<a href="http://\\2" target="_blank">\\2</a>', $message);
$message = eregi_replace('([[:space:]()[{}])(http://.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1<a href="\\2" target="_blank">\\2</a>', $message);
$message = eregi_replace("[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*", "<a href=\"mailto:\\0\">\\0</a>", $message);

fwrite($file, "\n[" . date("H:i:s") . "]  <b>" . $login . " => " . $who . "</b> : " . $message);
fwrite($filehis, "\n[" . date("H:i:s") . "]  <b>" . $login . " => " . $who . "</b> : " . $message);

header("Location:send.php?login=" . $login);
?>

Получив из файла send.php сообщение, мы должным образом форматируем его: выделяем e-mail`ы, адреса сайтов, с помощью символов «=>» разделяем, кто к кому обращается и выделяем обращение жирным шрифтом. Потом открываем файл chat.txt и добавляем в его конец новую строку, содержащую только что отформатированную реплику. После этого возвращаем посетителя обратно к send.php.

Del.php

Наконец, мы подошли к самому интересному месту работы чата. Как я уже упоминал в начале статьи, перед нами возникает проблема. Если человек просто обновляет окно чата, то мы с ним ничего не делаем, а если закрывает окно чата, то удаляем его из списка активных посетителей. Как этого добиться? Смотрите, как работает файл del.php.

<?php
error_reporting(0);
include("includer.php");
$login = $_GET['login'];
$db = mysql_connect($myserver, $mylogin, $mypassword);
mysql_select_db("micro");
$sql = "SELECT * FROM `chat_users` WHERE `login` = '".$login."'";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$id = $row["id"];
$password = $row["password"];
$privat = $row["privat"];
$sql = "DELETE FROM `chat_users` WHERE `id` = ".$id;
$result = mysql_query($sql);
$sql = "INSERT INTO `chat_users` VALUES ('', '".$login."', '".$password."', '".$privat."', '0')";
$result = mysql_query($sql);
Header("Location:index.php");
?>

На самом деле при любом изменении документа мы выставляем пользователю в «active» значение 0. Но если пользователь уходит, то это значение 0 так и останется в его профиле, а если пользователь просто обновляет страницу, то сценарий del.php сначала заносит в профиль пользователя значение 0, а потом, после обновления, сценарий chat.php заносит в профиль этого пользователя значение 1. То есть, по сути для пользователя ничего не меняется – он вышел, и его логин убирается из списка активных посетителей, обновил страницу – и все нормально, работает так, как и должно было работать.

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

Ну, а в следующей статье мы расширим возможности нашего чата: создадим для пользователей возможность пообщаться в «привате», интерфейс администрирования чата, а также сценарий админа, который будет реагировать на все происходящее в чате, который будет что-нибудь объявлять и, возможно, сможет отвечать на простые вопросы.