• Уважаемый посетитель!!!
    Если Вы уже являетесь зарегистрированным участником проекта "миХей.ру - дискусcионный клуб",
    пожалуйста, восстановите свой пароль самостоятельно, либо свяжитесь с администратором через Телеграм.

Php - пишем простой чат

  • Автор темы Автор темы Vaulter
  • Дата начала Дата начала

Vaulter

Участник
задался я мыслью, написать подобие чата....
как и все великое, начнется это с простых вещей....
1. чат будет на фреймах -
главный, с сообщениями
ввод, где будет вводится текст
список ников, понятно
и..фрейм "драйвер" всего этого дела )

2. будет юзать mySQL, потому как очень просто все тогда получится
3. в чате не будет регистрации, а следовательно админов и т.д., для простоты реализации и понятности...

итак, начнем...

заглав пага у нас будет index.html куда и будет попадать юзер при заходе на chat.test1.ru допустим ):
index.html
Код:
<html>

<frameset rows="0,50,*" onunload='alert(выход)'>
<frame NORESIZE FRAMEBORDER=0 name=dummy src=dummy.php>
<frame NORESIZE FRAMEBORDER=0 name=chat src=input.php>
<frameset cols="200,*" onunload='alert(выход)'>
	<frame NORESIZE FRAMEBORDER=0  name=nicklist src=users.php>
	<frame NORESIZE FRAMEBORDER=0  name=main src=main.php >
</frameset>
</frameset>
</html>

обьясняю - это страница фреймсет - набор фреймов,
первый фрейм, с нулевой высотой - "драйвер"...он будет перегружатся каждые...ну скажем 10 секунд, и проверять новые сообщения...пользователей убирать по тайм ауту и т.д.

второй фрейм ссылается на input.php..простенький скрипт, который будет принимать мессаги от юзера и пиндюрить их в БД нашу (кстати...)

третий - список ников...с js ссылками на вставку в input поле
ну и четвертый - где будут выводится все сообщения....


для чата нам понадобятся всего две таблицы (да, да ))):
Код:
CREATE TABLE `chat` (
  `userid` int(10) unsigned NOT NULL default '0',
  `message` varchar(255) NOT NULL default '0',
  `date` int(10) unsigned NOT NULL default '0',
  KEY `userid` (`userid`)
) TYPE=MyISAM;


CREATE TABLE `user` (
  `username` varchar(50) default NULL,
  `userid` int(10) unsigned NOT NULL auto_increment,
  `lastactivity` int(10) unsigned NOT NULL default '0',
  `lastupdate` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`userid`)
) TYPE=MyISAM;

тут кажется должно быть просто:
chat - три поля:
номер юзера (хотя надо было бы заносить имя а не ссылку на таблицу юзеров, так как при выходе стирается запись из user на которую будет ссылатся chat, ну да не страшно....
сам текст сообщения и время его...

user
имя, номер, последняя активность (для определения диссконнекта)
последний апдейт сообщений (чтобы проверять на наличие новых)


ну еще подготовимся...чтобы уж быть во всеоружие
напишем...functions.php всего с парой функций )
functions.php
PHP:
<?php

function setlocation($window,$time,$url)
{
if($time)echo "<script>top.$window.document.write(\"<META HTTP-EQUIV=Refresh 
CONTENT='$time; URL=$url'>\");</script>";
else	echo "<script>top.$window.location='$url'</script>";
}
function getdatestring($datest)
{
//writed by Vaulter 2003 )))))
    global $GMT;
    if($datest==0)return "никогда";
    $now=mktime()+$GMT;
    $datest+=$GMT;
$strdate=strftime("%H:%M:%S",$datest);

    return $strdate;
}
?>
первая просто выводит в страничку тег META REFRESH для перезагрузки какого либо фрейма, через указанный тайм, на указанный урл
вторая возвращает читаемую строку из UNIX TIMESTAMP....
поехали дальше?

Vaulter добавил [date]1076908879[/date]:
далее...начнем наш нелегкий труд...
напишем скриптик, который будет вызыватся для каждого скриптика...
в нем мы будет
1. коннектится к БД
2. начинать сессию
3. ставить текущему юзеру нашего чата, что он еще тут
4. и брать его статсы
5. переводить фокус на окошко ввода....
фух...
global.php
PHP:
<?php
error_reporting(E_ALL^E_NOTICE);
session_start();
$dbhost="localhost";
$dblogin="root";
$dbpass="";
$dbname="chat";//имя БД где наши таблицы
$dbconnect=mysql_connect($dbhost,$dblogin,$dbpass);
mysql_select_db($dbname);
//тут нет никаких проверок на ошибки, поэтому лучше чтобы 
//1. mySQL user с логином root был
//2. chat БД была )
//set activity if user loginned
if($_SESSION[userid])
{
	$query="UPDATE user SET lastactivity=".mktime()." WHERE userid=$_SESSION[userid]";
    @mysql_query($query);//апдейтим lastactivity и глушим вывод об ошибках, а нафиг они нам? )

	$query="SELECT * FROM user WHERE userid=$_SESSION[userid]";
    global $user;
    $user=mysql_fetch_assoc($res=mysql_query($query));//берез данные о юзере
    mysql_free_result($res);
    echo "<script>top.chat.document.forms[0].message.focus()</script>";//выводим js скрипт переводящий фокус куды надо
}
?>


далее, а очереди dummy.php, чуть ли не самый хлавный тут скрипт,
в его задачу входит
1. перегружать себя через каждые 10 секунд
2. удалять из таблицы чата старые сообщения
3. удалять юзеров по таймауту
4. перегружать соответсвующие фреймы

все просто:

PHP:
<?php
//engine to check new messages and reload chat window if need
set_time_limit(0);
if(connection_aborted())
{//we have to delete user from DB
	    $query="INSERT INTO chat VALUES ($user[userid],'? ????!!!!',".mktime().")";
	    @mysql_query($query);
        exit;
}
include 'functions.php';
include 'global.php';
//$s=@file('reload');
//header("location: ".$_SERVER['PHP_SELF']);
echo setlocation('dummy',10,'dummy.php');

//check for updating frames
	$r=0;
    $now=mktime()-5*60;//ten minutes
	$query="DELETE FROM chat WHERE date<$now";
    mysql_query($query);

	$query="DELETE FROM user WHERE lastactivity<$now";
    mysql_query($query);
    if(mysql_affected_rows())echo setlocation('nicklist',0,'users.php');//если есть удаленные записи то обновить ник лист

	$query="SELECT count(*) FROM chat,user ".
    "WHERE chat.date>user.lastupdate AND user.userid=$_SESSION[userid]";
    list($row)=mysql_fetch_array($res=mysql_query($query));
    mysql_free_result($res);
    if($row)echo setlocation('main',0,'main.php');
?>

Vaulter добавил [date]1076908970[/date]:
следующий на очереди input.php
скрипт подхватывающий сообщения юзера и заносящий их в БД...
input.php
PHP:
<?php
//input window
include 'functions.php';
include 'global.php';

if($_SESSION[userid])
{
	if($_SERVER['REQUEST_METHOD']=="POST"&&!empty($_POST[message]))
    {//parse form
	    $query="INSERT INTO chat VALUES ($user[userid],'".addslashes($_POST[message])."',".mktime().")";
	    @mysql_query($query);
        echo setlocation('main',0,'main.php');
    }


	echo"<center><form method=post>".
    "<input name=message type=text maxsize=250 size=50> <input type=submit value=Send></form><center>";
}
else echo "<center>Введи ник</center>";


?>
далее nicklist.php
здесь мы просто выводим кто сейчас у нас есть!
если кого нет, то я не виноват )

users.php
PHP:
<?php

//users
include 'functions.php';
include 'global.php';
$query = "SELECT * FROM user";
$result = mysql_query ($query) or exit(__FILE__." (".__LINE__.") ".$query);
print "<table>\n";
while ($line = mysql_fetch_assoc($result))
{
	echo "<tr><td><a  onclick='top.chat.document.forms[0].message.value+=\"$line[username], \"'>$line[username]</a>";

}
print "</table>\n";
echo setlocation("nicklist",60,$_SERVER[PHP_SELF]);
mysql_free_result($result);

?>

было бы логично тут же проверять старых юзеров, но я как то забыл об этом ))))
ну и наконец! main.php!!!

который:
1. логинит только что пришедшего
2. выводит сообщения для залогиненых
3. разлогинивает
4. ставит lastupdate для юзера (для проверки в dummy.php)

итак:
main.php
PHP:
<?php
error_reporting(E_ALL^E_NOTICE);
session_start();
session_register("userid");
@$action=$_GET[action];
include 'functions.php';
include 'global.php';
global $user;
echo "<html><body>";
if(empty($_SESSION[userid]))
{
	if($_SERVER[REQUEST_METHOD]=='POST')
    {//catch incoming nick
    	if(!empty($_POST[username]))
        {//check for existence
        	$query="SELECT userid FROM user WHERE username='".htmlspecialchars($_POST[username])."'";
            $r=mysql_query($query) or exit(__FILE__." (".__LINE__.") ".$query);
            if(mysql_num_rows($r))//if exists
            	echo "<center>Уже есть</center>";
			else //reg
            {
            	$query="INSERT INTO user (username,lastactivity) VALUES ('".
                htmlspecialchars($_POST[username]).
                "',".mktime().")";
                mysql_query($query) or exit(__FILE__." (".__LINE__.") ".$query);

	            $_SESSION[userid]=mysql_insert_id();
	            echo "<center>Привет, $_POST[username]</center>".
	            setlocation('chat',0,'input.php').
	            setlocation('main',2,'main.php');

	            echo "</body></html>";
	    $query="INSERT INTO chat VALUES ($_SESSION[userid],'я пришел!!!!',".mktime().")";
	    @mysql_query($query);
            }
        }
    }
    else
    {
	    echo "<form method=post>";
	    echo "<input type=text name=username size=30>";
	    echo "<input type=submit value=Enter>";
	    echo "</form></body></html>";
    }
	exit;
}
if($action=="exit")
{
	session_destroy();
    $query="INSERT INTO chat VALUES ($user[userid],'я ушел!!!!',".mktime().")";
    @mysql_query($query);
	$query="DELETE FROM user WHERE userid=$user[userid]";
    mysql_query($query);
    echo setlocation('main',0,'main.php');
    exit;
}
echo "<center>Чат для $user[username] <a href=main.php?action=exit>выйти</a></center>";
$query = "SELECT * FROM chat LEFT JOIN user USING (userid) ORDER BY date DESC";
$result = mysql_query ($query)  or die ("Query failed: $query");
print "<table>\n";
while ($line = mysql_fetch_assoc($result))
{
	echo "<tr><td>".getdatestring($line[date])." $line[username]: $line[message]";
}
print "</table>\n";
mysql_free_result($result);
$query="UPDATE user SET lastupdate=".mktime()." WHERE userid=$_SESSION[userid]";
@mysql_query($query);
echo "</body></html>";
?>

ну вот....все скрипты...
ничего сложного ;)
 
а теперь объясни людям находящимся на этом форуме как это все запустить на компе, LOL
biggthum.gif
 
А еще лучше было это все запихнуть в php И прилепить аттачем :)
 
P4eLa
эээээ...
на компе поставить Апачи с модулем PHP (альтернатива IIS+PHP но это мучатся сами будут)
и сервер mySQL
весь стафф (Apache+PHP+mySQL) мона скачать с www.dklab.ru и поставить под виндовозы (пакет Денвер)
потом почитать доки по Денверу....
и поставить этот чат ))

зы: нафига только на компе своем это делать? когда надо на хосте )
Speed
хм...не, не лучше! ) чтобы жизнь медом не казалась! )
 
Назад
Сверху