明輝手游網(wǎng)中心:是一個免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

PHP設(shè)計聊天室步步通

[摘要]聊天室可以采用完全自由的方式運(yùn)行,你可以隨意輸入呢稱,不用密碼,不保存你的聊天狀態(tài),優(yōu)點(diǎn)是:自由,非常適合于游客!另外一個方法是注冊聊天室,每個進(jìn)入聊天室的人都要輸入自己的用戶名和密碼才能進(jìn)入!優(yōu)點(diǎn):充分體現(xiàn)個性,非常適合于老朋友,他們的呢稱不會被人惡意侵占使用.我的聊天室使用注冊方法!   注冊...

  聊天室可以采用完全自由的方式運(yùn)行,你可以隨意輸入呢稱,不用密碼,不保存你的聊天狀態(tài),優(yōu)點(diǎn)是:自由,非常適合于游客!另外一個方法是注冊聊天室,每個進(jìn)入聊天室的人都要輸入自己的用戶名和密碼才能進(jìn)入!優(yōu)點(diǎn):充分體現(xiàn)個性,非常適合于老朋友,他們的呢稱不會被人惡意侵占使用.我的聊天室使用注冊方法!

  注冊通常采用2種方法:

  1、先注冊然后進(jìn)入聊天
  
    2、自動注冊

  然后在里面修改自己的資料!我采用第2種方法!!每個新進(jìn)入的聊友的用戶名會被自動保存到注冊到數(shù)據(jù)庫內(nèi),下次登陸必須輸入準(zhǔn)確的密碼才能進(jìn)入!

  下面是判斷部分!本程序使用文本數(shù)據(jù)庫!

//$useronline為在線人的數(shù)據(jù)文件名稱
//$useronlinelock為在線人的鎖定標(biāo)志
//$register為已經(jīng)注冊的數(shù)據(jù)文件名稱
//$registerlock為注冊文件的鎖定標(biāo)志
//$split為分隔符

//登陸參數(shù) enter
if($action == "enter")
{
//當(dāng)前時間秒數(shù)
$timecurrent = date("U");

//鎖定在線人數(shù)文件,防止同時修改同一個文件
while( file_exists($useronlinelock))
{
if(!file_exists($useronlinelock))
{
break;
}
}

//創(chuàng)建臨時文件
fclose(fopen($useronlinelock,"w"));

//讀入在線用戶和已經(jīng)注冊用戶的信息:密碼,昵稱,更新時間
$useronline = file($useronline);
$register = file($register);

//用于判斷登陸是否成功的標(biāo)志
$namesign=0;

//判斷用戶名,密碼的錯誤,用戶名不允許為空,不允許超過10個字符,密碼不允許超過20個字符
if(($name =="") (strlen($name) > 10) (strlen($pass) > 20) )
{
print("沒有昵稱或密碼過長");
//登陸失敗
$namesign=1;
//刪除臨時文件
unlink($useronlinelock);
}
else
{
//查找是否已經(jīng)有人注冊或者密碼錯誤
$foundsign=0;
for($i=0;$i<count($register);$i++)
{
//分割
$tempregister = split($split,$register[$i],99);
//找到已經(jīng)注冊的用戶名
if( $name == $tempregister[0] )
{
//已經(jīng)找到標(biāo)志
$foundsign=1;
//密碼正確嗎
if($pass != $tempregister[1])
print("密碼錯了!");
//登陸失敗
$namesign=1;
unlink($useronlinelock);
break;
}
else
{
//老用戶登陸成功
$namesign=0;
break;
}
}

}

//如果沒有找到這個用戶名,那么就自動注冊
if(!$foundsign)
{
//保存用戶名和密碼
$handle = fopen($register,"a");
fputs($handle,"$name$split$pass$splitrn");
fclose($handle);
//新用戶登陸成功
$namesign=0;
}
}
}
if(!$namesign)
{
//更新在線人的名單
$useronlinehandle = fopen($useronline,"w");

//判斷是否已經(jīng)在里面,只是刷新頁面
$updatesign = 0;
for($i=0;$i<count($useronline);$i++)
{
$usertemp=split($split,chop($useronline[$i]),99);
if($name == $usertemp[0])
{
//更新標(biāo)志
$updatesign = 1;
fputs($useronlinehandle,$useronline[$i]);
}
else
{
fputs($useronlinehandle,$useronline[$i]);
}
}
//如果沒有在里面,則增加到里面
if(!$updatesign)
fputs($useronlinehandle,"$name$split$level$split$pass$split$timecurren
trn");
fclose($useronlinehandle);

//去掉縮定
unlink($useronlinelock);

//登陸成功

  到這里,用戶的驗(yàn)證已經(jīng)完成,聊友已經(jīng)合法的進(jìn)入了聊天室,攜帶者呢稱和密碼


  登錄

  1、頁面登陸的基本要素

  你可以在我的竹葉看到登陸的表單,這里提供了最基本的登陸表單項

  (1)登陸表單

<form method=POST name=chatform action=chat/login.php?action=enter onSubmit="b1_submit();return true;" target="howtodo">

  (a)聊天表單的名字為chatform,我使用action=enter作為進(jìn)入聊天室的入口,如果沒有這個參數(shù),則顯示登陸頁面.

  (b)在表單提交時,先調(diào)用b1_submit()建立聊天的窗口

  (c)聊天的目標(biāo)窗口為b1_submit()建立的howtodo窗口

  (2)表單項

昵稱:<input type=text name=name size=15 maxlength="10">
密碼:<input type=password name=pass size=15 maxlength="10">
<input type=submit name=submit value=登陸 style="width:100">
<input type=reset name=reset value=重添 style="width:50">


(a)各表單項一定要設(shè)定最大允許長度 maxlength

  (3)建立聊天窗口的js

<script LANGUAGE="javascript">
function b1_submit(){
chat=window.open('',"howtodo",'Status=no,scrollbars=no,resizable=no');

chat.moveTo(0,0);
chat.resizeTo(screen.availWidth,screen.availHeight);
chat.outerWidth=screen.availWidth;
chat.outerHeight=screen.availHeight;

  這段代碼先打開一個沒有狀態(tài)欄,滾動條,可調(diào)整尺寸的howtodo窗口!然后移動到屏幕左上角,然后放大到允許的屏幕大小.

  在線人數(shù)

  我根據(jù)網(wǎng)易聊天室的在線人數(shù)的方法,顯示當(dāng)前的在線人數(shù),代碼解釋如下:
  1、登陸時建立在線人名單的數(shù)組,放在body后面

<?
//鎖定在線人數(shù)文件
while(file_exists($useronlinelock)){$pppp++;}
fclose(fopen($useronlinelock,"w"));

//讀入在線人名單
$useronline = file($useronline);
unlink($useronlinelock);

//建立數(shù)組 list
print("document.writeln("list=new Array(");
$k=count($useronline);
if($k>1)
{
for($i=0;$i<($k-1);$i++)
{
$usercurrent = split($split,$useronline[$i],99);
// 姓名+,
print("'$usercurrent[0]',");
}
$i=$k-1;
// 處理最后一個姓名
$usercurrent = split($split,$useronline[$i],99);
print("'$usercurrent[0]'");
}
// 數(shù)組結(jié)束
print(")");n");
?> 

  2、顯示在線人數(shù)的js

document.writeln('[在線人數(shù)<font color=red>'+count+'</font>]<br>');
document.writeln("[<a href="javascript:parent.cs('所有人')">所有人</
a>]<br>");
document.writeln("<font class='p9'>");
var j,name,club;
for(var i=0;i<list.length;i=i+1)
{
if(list[i]!=null){

//顯示每個在線人的名字
document.writeln("<a href="javascript:parent.cs('"+list[i]+"')" titl
e='"+list[i]+"'>"+list[i]+"</a><br>");
}
}
this.r.document.writeln('</font><hr>'); 

  3、改變聊天對象

function cs(name)
{
if(this.d.document==null)return;
if(name=='所有人')
{
this.d.add('所有人');
this.d.document.inputform.talkto.value='所有人';

//改變焦點(diǎn)
this.d.document.inputform.msg.focus();
return;
}
for(var i=0;i<list.length;i=i+1)
{
if(list[i]==name)
{

//更改發(fā)送的談話對象
this.d.document.inputform.talkto.value=list[i];
this.d.document.inputform.msg.focus();
return;
}
}

//錯誤
alert('此用戶已離線或已改了昵稱。');

  4、刪除一個用戶

function del(str)
{
for(var i=0;i<list.length;i=i+1)
if(list[i]==str)
{
delete list[i];
count--;
}

  5、增加一個用戶

function add(str1,str2)
{
var l=list.length;
for(var i=0;i<list.length;i=i+1)

//如果已經(jīng)在數(shù)組里面則返回
if(list[i]==str1)
return;

//增加一個用戶
list[l]=str1;
count++;

  6、更新聊天人數(shù)的方法,定時器的使用

var timerID=null;
var timerRunning=false;

function stop()
{
//停止
if(timerRunning)clearTimeout(timerID);
timerRunning=false;
}
function start()
{
stop();
//調(diào)用更新在線人數(shù)的程序
write1();
}

function write1()
{
... ... ... ...
//設(shè)定更新時間,
timerID=setTimeout("start()",30000);
timerRunning=true;

  這種方法比較簡單的實(shí)現(xiàn)了在線人數(shù)的顯示,當(dāng)然也可以使用讀入在線人文件的方法顯示在線人數(shù),不過在改變聊天對象是會比較麻煩.

  顯示

  現(xiàn)在的www聊天室基本全部采用框架方式,可以用frame也可以用iframe看個人喜歡了,我的采用frame的傳統(tǒng)方式

print("<frameset rows="*,110,0,0,0" border=0>n");
print("<frameset cols="660,118" rows="*">n");

//主顯示屏幕,負(fù)責(zé)顯示聊天內(nèi)容
print("<frame name=u src=about:blank frameborder="NO" noresize>n");


//在線人數(shù)屏幕
print("<frame name=r src="about:blank" frameborder="NO">");
print("</frameset>n");

//發(fā)送信息的屏幕,信息指揮中心,所有指令都要由這里發(fā)出
print("<frame name=d src=send.php?name=$name&&pass=$pass scrolling='no
' frameborder="NO" noresize>n");

//被動更新屏幕,處理發(fā)送的信息
print("<frame src="about:blank" name="bl">n");

/主動更新屏幕,顯示自己和其他聊友的聊天信息
print("<frame src="about:blank" name="flush">n");

//檢測是否在線的屏幕,對于異常離開,如死機(jī),掉線等的處理
print("<frame src="about:blank" name="check">n");
print("</frameset>n"); 

  因?yàn)楦鱾頁面之間的程序有聯(lián)系,所以顯示順序很重要,可以看到,我這里只有發(fā)送頁面不是about:blank,其他頁面的顯示都要先通過發(fā)送頁面的調(diào)用才能開始.


  指揮中心

  這里是聊天室的指揮中心,所有的指令都要在這里發(fā)出
  1、下面是基本的發(fā)送表單代碼

<form name=inputform action='messagesend.php' target='bl' onsubmit='return(checksay());' method=POST>

<?
//下面的2個參數(shù)用于驗(yàn)證信息的正確性
print("<input type='hidden' name='name' value='$name'>n");
print("<input type='hidden' name='pass' value='$pass'>n");
?>

//聊天對象,注意加上 readonly 屬性
<input type="text" name="talkto" size="10" maxlength="20" readonly value="所有人">

//上次聊天的發(fā)送內(nèi)容
<input type='hidden' name='message' value=''>

//發(fā)送的表單文本框
<input type="text" name="msg" maxlength="120" size="34">

<input type="submit" name="Submit" value="發(fā)送">

</form> 

  2 檢查發(fā)送內(nèi)容的js

var dx ='';
function checksay( )
{

//不允許發(fā)送空的發(fā)言
if(document.inputform.msg.value=='')
{
document.inputform.msg.focus();
return false;
}

//不允許重復(fù)發(fā)言,內(nèi)容相同,對象相同
if ((document.inputform.msg.value==document.inputform.message.value)
&&(document.inputform.talkto.value==dx))
{
alert('發(fā)言不能重復(fù)');
document.inputform.msg.focus();
return false;
}

//兩次發(fā)言內(nèi)容的間隔不能小于1秒,或者發(fā)言字?jǐn)?shù)大于間隔*3
t2=(new Date()).getTime()/1000;
if(((t2-t1)<1) ((t2-t1)*3<document.inputform.msg.value.length))
{
document.inputform.msg.focus();
return false;
}

//更新時間
t1=t2;

document.inputform.showsign.value=1;

//保存上次發(fā)言內(nèi)容
document.inputform.message.value =document.inputform.msg.value;

//清空發(fā)言內(nèi)容
document.inputform.msg.value ='';

//保存發(fā)言對象
dx=document.inputform.talkto.value;

//定位焦點(diǎn)
document.inputform.msg.focus();

//返回
return(true);

  3、調(diào)用信息發(fā)送程序,發(fā)布聊天者已經(jīng)進(jìn)入的信息

<script>
parent.bl.document.open();
parent.bl.document.write("<meta http-equiv='refresh' content='0;url=messagesend.php?name=<? print($name); ?>&&action=enter&&pass=<? print($pass); ?>'>")
parent.bl.document.close();
</script> 

  發(fā)言由messagesend.php處理完成,注意輸出對象為bl,也就是處理發(fā)言的框架名稱,這樣保證發(fā)言框架的頁面內(nèi)容的完整

  表情和動作

  表情和動作極大的豐富了聊天的樂趣,一般的聊天室主要通過2種方法發(fā)送

  (1) 按鈕菜單的方法

  通過在一個固定的下拉菜單里面進(jìn)行選擇,找到自己滿意的表情,然后選中,按發(fā)送按鈕發(fā)出

  (2) 通過手工輸入代號

  比如網(wǎng)易的以手工輸入 //hello 代表歡迎的一段動作,以 //bye 代表再見的一段動作表情
  我們這里介紹菜單的具體實(shí)現(xiàn)方法,手工輸入的不用介紹了吧! 哈哈!除非你記不住那些...

  1 下拉菜單選擇表情動作的實(shí)現(xiàn)

  為了擴(kuò)充方便,我們制作了表情動作的數(shù)據(jù)文件,這樣在以后擴(kuò)充時將會非常方便.

  表情動作文件的格式如下($split代表分割符):

//1234$split“1234567,我的朋友在哪里1234!。。!”
//?$split很疑惑的看著對象...
//??$split抓呀抓,把頭皮都抓破了,也沒有想出個所以然來。
//???$split怎么回事?這到底是怎么回事

  前面的//1234代表表情動作代碼,分隔符后面的代表顯示的表情動作注意其中的 對象 兩個字將會在顯示時替換成為發(fā)言對象的名字

  這段代碼用于把菜單選擇的對應(yīng)的表情動作代碼寫到發(fā)送欄里面

<script>
function changemote($newemote)
{
document.inputform.msg.value = $newemote
}
</script>

  這段代碼生成動態(tài)下來菜單

<select name="select" onchange="changemote(this.options[this.selectedIndex].value)">
<o(jì)ption value="0" selected>動作</option>
<?
$emotemsg = file($emotefilename);
for($i=0;$i<count($emotemsg);$i++)
{
$msg = split($split,$emotemsg[$i],99);
print("<o(jì)ption value=$msg[0]>$msg[1]</option>");
}
?>
</select> 

  這樣就完成了從菜單選動作表情的過程

  2 表情動作在發(fā)言處理程序里的處理過程

messagesend.php

<?

//讀入表情動作文件
$emote3 = file($emotefilename);
$emote3number = count($emote3);
for($kk=0;$kk<$emote3number;$kk++)
{

//分割每個表情動作
$emote=split($split,chop($emote3[$kk]),99);

//如果發(fā)言內(nèi)容等于表情動作
if($message == $emote[0])
{

//替換表情動作里面的 對象 為實(shí)際的聊天對象名字
$emote[1]=ereg_replace("對象","<font color=red>$talkto</font>",$emote[1]);

//發(fā)言內(nèi)容改為動作表情的內(nèi)容
$message = "<a href=javascript:parent.cs('$name') target=d>$name</a
>".$emote[1];
break;
}
}
?> 

  這樣我們就實(shí)現(xiàn)了表情和動作,如果做一個自動添加動作表情的程序功能,更會增加聊天的娛樂性!

  帖圖

  如果在聊天文字中能增加一些美麗的圖片.......
  圖片代碼的生成和表情動作一樣,可以菜單選擇也可以手工輸入,這里只給出格式和代碼,不再解釋,請察看 表情于動作部分

  1 文件格式

//$picturefilename

1$split咖啡色西服$splitxw20151.jpg$split
2$split黑色燕尾服$splitxw201534.jpg$split

  編號+名稱+圖片名稱+

  2 程序

  我的聊天室采用 ///gift+編號的方法顯示圖片,注意是三個反斜杠,區(qū)別于表情動作

<?
//判斷發(fā)言的內(nèi)容最前面的7個字符是否是 ///gift
if(substr($message,0,7) == "http:///gift")
{

//取得圖片的編號,從第7個字符開始的2個字符(注意,字符從0開始編號)
$id = substr($message,7,2)-1;

//讀入圖片文件
$giftmsg = file($picturefilename);

//判斷是否編號合法
if(($id >= 0) && ($id < count($giftmsg)) )
{
//分割圖片行
$gift=split($split,$giftmsg[$id],99);

//生成圖片的發(fā)言內(nèi)容
$message ="<a href=javascript:parent.cs('$name') target=d><font col
or=$namecolor>$name</font></a>送給<a href=javascript:parent.cs('$talkt
o') target=d>$talkto</a>一個$gift[1]<img src='images/$gift[2]' width=6
0 height=60 border=0></font>";

//圖片生成成功標(biāo)志
$specialsign = 1;
}

  密談的實(shí)現(xiàn)

  每個聊天室都提供了密談功能,來為那些需要私下里進(jìn)行交流的聊友提供方便,這里把我的聊天室實(shí)現(xiàn)私聊的方法介紹如下:

  1 對發(fā)送信息的處理

  每句私聊都要顯示在自己和私聊對象的屏幕上,而其他人不能夠看到.這里先對發(fā)言內(nèi)容進(jìn)行處理,然后再保存到發(fā)言文件里面!

//$split為分隔符號

messagesend.php

<?
//判斷是否私聊發(fā)言
if($secret == "on")
{
//在發(fā)言前面加上標(biāo)記<!--+私聊標(biāo)記+對象+發(fā)言者+--> 其中+代表分隔符

//第一個標(biāo)記為 secret 表示為私聊,后面的是聊天對象和自己的名字,保證這兩個人能看到
$message = "<!--$splitsecret$split$talkto$split$name$split--><font c
olor=ff0000>密談</font>$message";
}
else
{

//如果第一個標(biāo)記為 open 表示公開,后面同樣為對象和自己的名字
$message = "<!--$splitopen$split$talkto$split$name$split-->$message"
;
}

//然后保存到文件中
?> 

  2 顯示私聊的方法

  對每個新的發(fā)言讀入后先進(jìn)行處理判斷,在主動刷新程序里面進(jìn)行.

messageflush.php

<?
//分割發(fā)言內(nèi)容
$tempmessage = split($split,$message[0],99);

//如果發(fā)言不是密談,或者私聊對象是自己,或者發(fā)送這句私聊的是自己,那就顯示這句話,否則不顯示
if( ($tempmessage[1] != "secret") ($tempmessage[2] == $name) (
$tempmessage[3] == $name) )
{

//顯示私聊
print("parent.u.document.writeln("$message[0]");rn");
}
?> 

  通過這種簡單的方法,我們實(shí)現(xiàn)了私聊,

  注意:

  前面的保存文件處理時,對發(fā)言的判斷文字前后有<!-- 和 -->這樣在屏幕顯示時就可以不用特殊處理了!