PHP设计聊天室步步通


Posted in PHP onOctober 09, 2006

聊天室可以采用完全自由的方式运行,你可以随意输入呢称,不用密码,不保存你的聊天状态,优点是:自由,非常适合于游客!另外一个方法是注册聊天室,每个进入聊天室的人都要输入自己的用户名和密码才能进入!优点:充分体现个性,非常适合于老朋友,他们的呢称不会被人恶意侵占使用.我的聊天室使用注册方法!

注册通常采用2种方法:

1、先注册然后进入聊天

 

2、自动注册

然后在里面修改自己的资料!我采用第2种方法!!每个新进入的聊友的用户名会被自动保存到注册到数据库内,下次登陆必须输入准确的密码才能进入!

下面是判断部分!本程序使用文本数据库!

//$useronline为在线人的数据文件名称
//$useronlinelock为在线人的锁定标志
//$register为已经注册的数据文件名称
//$registerlock为注册文件的锁定标志
//$split为分隔符

//登陆参数 enter
if($action == "enter")
{
//当前时间秒数
$timecurrent = date("U");

//锁定在线人数文件,防止同时修改同一个文件
while( file_exists($useronlinelock))
{
if(!file_exists($useronlinelock))
{
break;
}
}

//创建临时文件
fclose(fopen($useronlinelock,"w"));

//读入在线用户和已经注册用户的信息:密码,昵称,更新时间
$useronline = file($useronline);
$register = file($register);

//用于判断登陆是否成功的标志
$namesign=0;

//判断用户名,密码的错误,用户名不允许为空,不允许超过10个字符,密码不允许超过20个字符
if(($name =="") || (strlen($name) > 10) || (strlen($pass) > 20) )
{
print("没有昵称或密码过长");
//登陆失败
$namesign=1;
//删除临时文件
unlink($useronlinelock);
}
else
{
//查找是否已经有人注册或者密码错误
$foundsign=0;
for($i=0;$i<count($register);$i++)
{
//分割
$tempregister = split($split,$register[$i],99);
//找到已经注册的用户名
if( $name == $tempregister[0] )
{
//已经找到标志
$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");

//判断是否已经在里面,只是刷新页面
$updatesign = 0;
for($i=0;$i<count($useronline);$i++)
{
$usertemp=split($split,chop($useronline[$i]),99);
if($name == $usertemp[0])
{
//更新标志
$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);

//登陆成功

到这里,用户的验证已经完成,聊友已经合法的进入了聊天室,携带者呢称和密码

登录

1、页面登陆的基本要素

你可以在我的竹叶看到登陆的表单,这里提供了最基本的登陆表单项

(1)登陆表单

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

(a)聊天表单的名字为chatform,我使用action=enter作为进入聊天室的入口,如果没有这个参数,则显示登陆页面.

(b)在表单提交时,先调用b1_submit()建立聊天的窗口

(c)聊天的目标窗口为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)各表单项一定要设定最大允许长度 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;

这段代码先打开一个没有状态栏,滚动条,可调整尺寸的howtodo窗口!然后移动到屏幕左上角,然后放大到允许的屏幕大小.

在线人数

我根据网易聊天室的在线人数的方法,显示当前的在线人数,代码解释如下:

1、登陆时建立在线人名单的数组,放在body后面

<?
//锁定在线人数文件
while(file_exists($useronlinelock)){$pppp++;}
fclose(fopen($useronlinelock,"w"));

//读入在线人名单
$useronline = file($useronline);
unlink($useronlinelock);

//建立数组 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]'");
}
// 数组结束
print(")");n");
?> 

2、显示在线人数的js

document.writeln('[在线人数<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='所有人';

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

//更改发送的谈话对象
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)

//如果已经在数组里面则返回
if(list[i]==str1)
return;

//增加一个用户
list[l]=str1;
count++;

6、更新聊天人数的方法,定时器的使用

var timerID=null;
var timerRunning=false;

function stop()
{
//停止
if(timerRunning)clearTimeout(timerID);
timerRunning=false;
}
function start()
{
stop();
//调用更新在线人数的程序
write1();
}

function write1()
{
... ... ... ...
//设定更新时间,
timerID=setTimeout("start()",30000);
timerRunning=true;

这种方法比较简单的实现了在线人数的显示,当然也可以使用读入在线人文件的方法显示在线人数,不过在改变聊天对象是会比较麻烦.

显示

现在的www聊天室基本全部采用框架方式,可以用frame也可以用iframe看个人喜欢了,我的采用frame的传统方式

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

//主显示屏幕,负责显示聊天内容
print("<frame name=u src=about:blank frameborder="NO" noresize>n");

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

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

//被动更新屏幕,处理发送的信息
print("<frame src="about:blank" name="bl">n");

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

//检测是否在线的屏幕,对于异常离开,如死机,掉线等的处理
print("<frame src="about:blank" name="check">n");
print("</frameset>n"); 

因为各个页面之间的程序有联系,所以显示顺序很重要,可以看到,我这里只有发送页面不是about:blank,其他页面的显示都要先通过发送页面的调用才能开始.

指挥中心

这里是聊天室的指挥中心,所有的指令都要在这里发出

1、下面是基本的发送表单代码

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

<?
//下面的2个参数用于验证信息的正确性
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="所有人">

//上次聊天的发送内容
<input type='hidden' name='message' value=''>

//发送的表单文本框
<input type="text" name="msg" maxlength="120" size="34">

<input type="submit" name="Submit" value="发送">

</form> 

2 检查发送内容的js

var dx ='';
function checksay( )
{

//不允许发送空的发言
if(document.inputform.msg.value=='')
{
document.inputform.msg.focus();
return false;
}

//不允许重复发言,内容相同,对象相同
if ((document.inputform.msg.value==document.inputform.message.value)
&&(document.inputform.talkto.value==dx))
{
alert('发言不能重复');
document.inputform.msg.focus();
return false;
}

//两次发言内容的间隔不能小于1秒,或者发言字数大于间隔*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;

//保存上次发言内容
document.inputform.message.value =document.inputform.msg.value;

//清空发言内容
document.inputform.msg.value ='';

//保存发言对象
dx=document.inputform.talkto.value;

//定位焦点
document.inputform.msg.focus();

//返回
return(true);

3、调用信息发送程序,发布聊天者已经进入的信息

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

发言由messagesend.php处理完成,注意输出对象为bl,也就是处理发言的框架名称,这样保证发言框架的页面内容的完整

表情和动作

表情和动作极大的丰富了聊天的乐趣,一般的聊天室主要通过2种方法发送

(1) 按钮菜单的方法

通过在一个固定的下拉菜单里面进行选择,找到自己满意的表情,然后选中,按发送按钮发出

(2) 通过手工输入代号

比如网易的以手工输入 //hello 代表欢迎的一段动作,以 //bye 代表再见的一段动作表情

我们这里介绍菜单的具体实现方法,手工输入的不用介绍了吧! 哈哈!除非你记不住那些...

1 下拉菜单选择表情动作的实现

为了扩充方便,我们制作了表情动作的数据文件,这样在以后扩充时将会非常方便.

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

//1234$split“1234567,我的朋友在哪里1234!!!!!”
//?$split很疑惑的看着对象...
//??$split抓呀抓,把头皮都抓破了,也没有想出个所以然来。
//???$split怎么回事?这到底是怎么回事

前面的//1234代表表情动作代码,分隔符后面的代表显示的表情动作注意其中的 对象 两个字将会在显示时替换成为发言对象的名字

这段代码用于把菜单选择的对应的表情动作代码写到发送栏里面

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

这段代码生成动态下来菜单

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

这样就完成了从菜单选动作表情的过程

2 表情动作在发言处理程序里的处理过程

messagesend.php

<?

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

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

//如果发言内容等于表情动作
if($message == $emote[0])
{

//替换表情动作里面的 对象 为实际的聊天对象名字
$emote[1]=ereg_replace("对象","<font color=red>$talkto</font>",$emote[1]);

//发言内容改为动作表情的内容
$message = "<a href=javascript:parent.cs('$name') target=d>$name</a
>".$emote[1];
break;
}
}
?> 

这样我们就实现了表情和动作,如果做一个自动添加动作表情的程序功能,更会增加聊天的娱乐性!

帖图

如果在聊天文字中能增加一些美丽的图片.......

图片代码的生成和表情动作一样,可以菜单选择也可以手工输入,这里只给出格式和代码,不再解释,请察看 表情于动作部分

1 文件格式

//$picturefilename

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

编号+名称+图片名称+

2 程序

我的聊天室采用 ///gift+编号的方法显示图片,注意是三个反斜杠,区别于表情动作

<?
//判断发言的内容最前面的7个字符是否是 ///gift
if(substr($message,0,7) == "///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);

//生成图片的发言内容
$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>";

//图片生成成功标志
$specialsign = 1;
}

密谈的实现

每个聊天室都提供了密谈功能,来为那些需要私下里进行交流的聊友提供方便,这里把我的聊天室实现私聊的方法介绍如下:

1 对发送信息的处理

每句私聊都要显示在自己和私聊对象的屏幕上,而其他人不能够看到.这里先对发言内容进行处理,然后再保存到发言文件里面!

//$split为分隔符号

messagesend.php

<?
//判断是否私聊发言
if($secret == "on")
{
//在发言前面加上标记<!--+私聊标记+对象+发言者+--> 其中+代表分隔符

//第一个标记为 secret 表示为私聊,后面的是聊天对象和自己的名字,保证这两个人能看到
$message = "<!--$splitsecret$split$talkto$split$name$split--><font c
olor=ff0000>密谈</font>$message";
}
else
{

//如果第一个标记为 open 表示公开,后面同样为对象和自己的名字
$message = "<!--$splitopen$split$talkto$split$name$split-->$message"

}

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

2 显示私聊的方法

对每个新的发言读入后先进行处理判断,在主动刷新程序里面进行.

messageflush.php

<?
//分割发言内容
$tempmessage = split($split,$message[0],99);

//如果发言不是密谈,或者私聊对象是自己,或者发送这句私聊的是自己,那就显示这句话,否则不显示
if( ($tempmessage[1] != "secret") || ($tempmessage[2] == $name) || (
$tempmessage[3] == $name) )
{

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

通过这种简单的方法,我们实现了私聊,

注意:

前面的保存文件处理时,对发言的判断文字前后有<!-- 和 -->这样在屏幕显示时就可以不用特殊处理了!

PHP 相关文章推荐
虚拟主机中对PHP的特殊设置
Oct 09 PHP
php设计模式 Observer(观察者模式)
Jun 26 PHP
php启动时候提示PHP startup的解决方法
May 07 PHP
分割GBK中文遭遇乱码的解决方法
Aug 09 PHP
探寻PHP脚本不报错的原因
Jun 12 PHP
php生成图片缩略图的方法
Apr 07 PHP
PHP简单实现无限级分类的方法
May 13 PHP
Laravel5.1自定义500错误页面示例
Oct 09 PHP
[原创]php集成安装包wampserver修改密码后phpmyadmin无法登陆的解决方法
Nov 23 PHP
PHPMailer发送邮件
Dec 28 PHP
PHP实现文件下载【实例分享】
Apr 28 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
Dec 18 PHP
编写PHP的安全策略
Oct 09 #PHP
MVC模式的PHP实现
Oct 09 #PHP
使用PHP和XSL stylesheets转换XML文档
Oct 09 #PHP
将PHP作为Shell脚本语言使用
Oct 09 #PHP
PHP分页显示制作详细讲解
Oct 09 #PHP
用PHP调用Oracle存储过程
Oct 09 #PHP
不用GD库生成当前时间的PNG格式图象的程序
Oct 09 #PHP
You might like
如何用php生成扭曲及旋转的验证码图片
2013/06/07 PHP
thinkphp中html:list标签传递多个参数实例
2014/10/30 PHP
php实现CSV文件导入和导出
2015/10/24 PHP
JavaScript学习历程和心得小结
2010/08/16 Javascript
JS打开层/关闭层/移动层动画效果的实例代码
2013/05/11 Javascript
js有序数组的连接问题
2013/10/01 Javascript
jquery插件开发之实现md5插件
2014/03/17 Javascript
ExtJS4利根据登录后不同的角色分配不同的树形菜单
2014/05/02 Javascript
javascript版2048小游戏
2015/03/18 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
2015/10/28 Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
2016/02/25 Javascript
JavaScript中Array的实用操作技巧分享
2016/09/11 Javascript
Vue.js组件tree实现省市多级联动
2016/12/02 Javascript
Vue.js在使用中的一些注意知识点
2017/04/29 Javascript
JavaScript中的FileReader图片预览上传功能实现代码
2017/07/24 Javascript
深入讲解xhr(XMLHttpRequest)/jsonp请求之abort
2017/07/26 Javascript
JS传播事件、取消事件默认行为、阻止事件传播详解
2017/08/14 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
微信小程序class封装http代码实例
2019/08/24 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
python学习之编写查询ip程序
2016/02/27 Python
Python实现队列的方法示例小结【数组,链表】
2020/02/22 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
Python利用matplotlib绘制散点图的新手教程
2020/11/05 Python
css3中的calc函数浅析
2018/07/10 HTML / CSS
字符串str除首尾字符外的其他字符按升序排列
2013/03/08 面试题
大学生农村教师实习自我鉴定
2013/09/21 职场文书
珍珠奶茶店创业计划书
2014/01/11 职场文书
给医务人员表扬信
2014/01/12 职场文书
打造完美自荐信
2014/01/24 职场文书
计算机学生求职信范文
2014/01/30 职场文书
看雷锋电影观后感
2015/06/10 职场文书
创业计划书之宠物店
2019/09/19 职场文书