jacking
级别: 论坛版主
UID: 2
精华: 2
发帖: 295
威望: 309 点
金钱: 2990 RMB
贡献值: 0 点
注册时间:2007-05-17
最后登录:2008-12-31
楼主  发表于: 2007-12-23 12:34

 PHP+AJAX+HTML打造无刷新聊天室{老技术新用}


又是工作需要,算是再次的学习ajax吧,作为一个web程序员,这个技术是必须懂的.因为好多地方都会用到.....
========================================================================

记得在很早上网的时候,还没有什么流行的即时通讯软件,更多的人是用WEB程序编写的聊天室来进行网上交流。每次页面刷新的“嗒嗒”声似乎还在耳边回响。

时过境迁,现在很少有人会提到聊天室程序了,但有了AJAX,似乎不需要iframe和meta的帮助也能实现即时信息的刷新,我们何不动手做一套属于自己的聊天室呢?^_^

准备活动
在开始前,检查下自己是否满足下面这些基本条件

有PHP语言方面的基础 
有javascript方面的知识 
HTML语言基础 
如果您对以上三个知识点都有所了解,那么相信下面的内容应该难不倒您。我们推荐刚接触这方面知识的朋友先去我们的知识库充充电,了解之后回头这些内容会对您更有帮助。好了,现在开始切入正题。

查看效果,了解大概的功能
在看过具体的效果后,大家可以先自己思考下。

我把程序所用到的文件和大概的用途,给大家指明一下:

-
|-文件夹:data
    | yy-m-d.html  每天会建立以日期命名的hmtl文件,记录聊天的内容
|-文件夹:inc
    | ja.js        里面存放着AJAX核心函数
| default.php      显示聊天记录,输入聊天内容的主页面
| hello.php        处理新来用户的呢称存储
| save.php        保存用户的聊天内容
| read.php        读取聊天内容

好了,就这么点,当然了你可以发挥自己的想象力把它弄的更完美一些。

第一步:判断是否需要建立新的html
如果你想让程序每天自动创建一个新的HTML文件来记录聊天信息的话,这步就少不了了。

提示:先检查data文件夹下今天的文件是否存在,不存在则建立一个空的文件。

所要用到的函数有:file_exists()和file_put_contents()

copycode
  1. <?php
  2. //在default.php的顶部
  3. $tfile= 'data/'.date('y-m-d').'.html'; //今天文件的位置
  4. if(!file_exists($tfile))                    //判断是否存在
  5. file_put_contents($tfile,'');              //不存在则建立一个内容为空的文件
  6. ?>

jacking
级别: 论坛版主
UID: 2
精华: 2
发帖: 295
威望: 309 点
金钱: 2990 RMB
贡献值: 0 点
注册时间:2007-05-17
最后登录:2008-12-31
1楼  发表于: 2007-12-24 09:48
第二步:判断是否是新来的用户
我们使用了cookie,当然session也是可行的

过程:在default.php页判断当前用户是否是第一次来访,是的话要求其输入昵称,昵称发送到hello.php生成一个10小时有效的cookie。然后返回到default.php页,此时可以进行信息的输入

copycode
  1. <?php
  2. if(!$_COOKIE['user'])
  3. //当COOKIE不存在↓
  4. echo <<<_html
  5. <form action="hello.php" method="post">
  6. <input type="text" name="user" value="输入昵称->提交->聊天" onclick="this.value=''" />
  7. <input type="submit" value="提交" />
  8. </form>
  9. _html;
  10. else
  11. //存在就显示聊天信息输入的区域↓
  12. echo <<<_html
  13. <textarea name="nmsg" id="nmsg" onkeydown="ctrl_enter(event)"></textarea>
  14. <button onclick="save()" id="update">Ctrl+回车</button>
  15. _html;
  16. ?>


完成hello.php对新来用户昵称的cookie写入
在default.php页得到一个来自新用户的昵称post之后,页面会转向hello.php

处理cookie的方法是使用setcookie('cookie名称','cookie值',过期时间)

注意 处理cookie必须在html标签之前(在有任何信息输出之前)



程序代码
copycode
  1. <?php
  2. if($_POST['user']){                      //判断是否获取到了post数据
  3. $name = urlencode($_POST['user']);        //对内容进行url加密
  4. setcookie('user',$name,time()+36000);    //当前时间再加上36000毫秒的有效时间(10小时后过期)
  5. }
  6. header("location: default.php");            //返回到default.php
  7. ?>
jacking
级别: 论坛版主
UID: 2
精华: 2
发帖: 295
威望: 309 点
金钱: 2990 RMB
贡献值: 0 点
注册时间:2007-05-17
最后登录:2008-12-31
2楼  发表于: 2007-12-24 09:51
第三步:完成信息的写入工作
当用户的浏览器有了昵称信息,并往写了一些信息,完成后JS负责建立一条类似于后台处理的线路,将数据以post的形式发送给save.php,大家可以先看一下这个JS文件里的save函数

注意JS传递的信息的字符编码都是utf-8的,所以在save.php我们需要将得到的post信息再转换成gb2312。PHP有个非常不错的函数iconv(),可以很方便的将utf-8转成gb2312



程序代码
copycode
  1. <?php
  2. //设置时区,默认时区和中国时区相差8个小时,可以在php.ini文件里设置
  3. ini_set('date.timezone','Asia/Shanghai');
  4. //当post有内容,并且cookie存在时
  5. if($_POST['nmsg'] && $_COOKIE['user']){
  6. $file_url = 'data/'.date('y-m-d').'.html'; //当日文件所在位置
  7. $dd = date('H:i:s');                          //当前时间
  8. $name = urldecode($_COOKIE['user']);          //将cookie里的内容解码
  9. //祛除一些特殊标记
  10. $new_msg = str_replace("&","&",$_POST['nmsg']);
  11. $new_msg = str_replace("<","<",$new_msg);
  12. $new_msg = str_replace(">",">",$new_msg);
  13. $new_msg = str_replace("\n","<br />",$new_msg);
  14. $new_msg = str_replace("\r","",$new_msg);
  15. $new_msg = iconv('utf-8','gb2312',$new_msg); //字符编码转换
  16. $fp = fopen($file_url,'a');                    //追加信息
  17. fwrite($fp,"<p><b>$name</b><small>$dd</small><pre>$new_msg</pre></p>\n");
  18. fclose($fp);
  19. }
  20. ?>

提示:因为IE和FF浏览器里对回车符号这个概念不太一致,所以在将\n转成<br />后我还将\r转成了空字符。这样可以避免逐行读取的时候出现偏差

第四步:隔时刷新读取数据
主要功臣还是js,但我们这里只对read.php做一下解释,因为对于AJAX核心函数其实并没有什么可以多说的,只是几个参数的改动,大家可以前往AJAX框架了解一下,我们的AJAX教程上也有一些介绍。

read.php要得到vnum参数的值,它关系到在default.php上显示几条记录,而这个值由default.php中的下拉菜单来控制:

显示<select id="vnum" onchange="sendPostRequest(this.value)">
<option value="10" selected="selected">10条</option>
<option value="20">20条</option>
<option value="30">30条</option>
</select> 记录

当选项发生改变就将参数交给sendPostRequest(),然后显示的条目就会发生改变。

我们来看看read.php干了什么事:



程序代码
copycode
  1. <?php
  2. //因为浏览器对于浏览器过的页面会有缓存,而这张页面会不时的刷出新的信息,所以我们要强制把缓存关闭
  3. header("Cache-Control: no-cache");
  4. header("Pragma: no-cache");
  5. //信息文件地址
  6. $file_url = 'data/'.date('y-m-d').'.html';
  7. //先将文件内容以数组的形式提取出来,然后再进行方向读取(读取比较新的信息)
  8. $msg = array_reverse(file($file_url));
  9. //判断参数,依其做出相应处理
  10. switch ($_GET['vnum']){
  11.    
  12.     case '10':
  13.     for($num=10;$num>=0;$num--){
  14.     echo iconv('gb2312','utf-8',$msg[$num]); //将gb2312再转成utf-8让js传送
  15.     }
  16.     break;
  17.    
  18.     case '20':
  19.     for($num=20;$num>=0;$num--){
  20.     echo iconv('gb2312','utf-8',$msg[$num]);
  21.     }
  22.     break;
  23.    
  24.     case '30':
  25.     for($num=30;$num>=0;$num--){
  26.     echo iconv('gb2312','utf-8',$msg[$num]);
  27.     }
  28.     break;
  29.     default:
  30.     echo "参数错误!";                          //无参数就显示错误
  31.     break;
  32. }
  33. ?>


最后一步:下载代码,自己研究 ^_^
本人只是把每个文件是做什么的做了下解释,其实这个聊天室功能非常的简单,大家可以发挥自己的才智把它弄的更好一些。这里是代码地址
jacking
级别: 论坛版主
UID: 2
精华: 2
发帖: 295
威望: 309 点
金钱: 2990 RMB
贡献值: 0 点
注册时间:2007-05-17
最后登录:2008-12-31
3楼  发表于: 2007-12-25 08:47
自娱自乐~ 今天再学习之.....