使用PHP+MYSQL+JS实现聊天功能

  • 来源: 博客园 作者: 戴九军   2011-05-27/15:05
  •       其实为了实现这个聊天的功能我也是寻找了很多资料,实现这个聊天功能还是有很多缺陷,例如只能是一对一聊天,不能同时支持一个人对多个人聊天、不支持发送同样的消息,还有不支持的就是发送的第一个信息不能是1。下面我介绍一下我的实现方法,也希望更多的牛人能够给我指点迷津,让我们共同的把这个网页聊天功能实现的更强大,也可以作为开源代码给大家互相学习。
          首先介绍一下数据库,数据库有三个表是和这个功能实现有关的,一个是user,主要是存储用户的信息其中包含了用户的姓名、帐号、密码等信息。如下图:
    包含的信息只是与接下来讲解的有关的属性。
     


    第二表,这个表有四个属性,分别是id、userId、friendId、friendType。相信大家根据字面意思都能够明白表中的属性意思:下面是表的截图:
     



    第三个表是我们的chating表,这个表就是用户与用户建立聊天的表,有如下属性:
     


     


          这里我分成两个截图显示,其中的personId就是发起聊天的用户,friendId就是接受聊天的用户,contentToFriend就是person发送给friend的信息,而contentToperson就是friend发送给person的信息,其他的属性就无需讲解了。
          至此,如果大家想实现这个聊天功能的话,只需要建立这三个表就行了。下面我们开始讲解主题实现:
          首先我们从数据层开始:数据层有三个类分别对应三个表,然后属性对应类中的相应的私有变量,然后有三个对应的数据库操作函数(删除、添加、根据属性获取id等等数据库操作函数)分别可以命名为,userFunction、friendListFunction、chatingFunction。
          最后讲解我们的逻辑层实现,这是关键一步:这里会涉及六个文件。

    #p#副标题#e#
          chating_with_friend.php:
          主要是显示出user的所有好友,例如如下代码:

    1. <ul>
    2.                                 <li><a href="#" onclick="displayfriend('one')">最近联系人</a></li>
    3.                                 <ul  class="dispalyfriend" id="one">
    4.                                 <a href="#" onclick="getbacknodisplay('one')">缩放</a>
    5.                 <?php
    6.                 foreach($friendList as $friend ){
    7.                         $friendType = $friend->get_friendType();
    8.                         $friendId = $friend->get_friendId();
    9.                         $user = get_user($friendId);
    10.                         $userName = $user->get_userName();
    11.                         if($friendType == 0){
    12.                                 ?>
    13.                                 <li><a href="#" onclick="connectFriend(<?php echo $friendId;?>,<?php echo $userId;?>,<?php echo $user->get_headPicture();?>)"><img style="width:20px" src="../imgs/headPicture/<?php echo $user->get_headPicture();?>.jpg"><?php echo $userName;?></a></li>
    14.                                 <?php
    15.                         }
    16.                 }
    17.                 ?>
    18.                                 </ul>
    复制代码

    这里只是显示所有的user的最近联系人的列表,关键就是遍历数据库查找所有为最近联系人的好友id,然后根据id得到user类,就可以显示所有信息。
    其中

    这段代码,显示用户,如果点击用户头像或者用户昵称,就会触发一个connectFriend函数,而且会传入三个参数分别是connectFriend(friendId,userId,headPicture),下面我们简单看一下这个函数,这个函数在chating.js文件中代码如下:

    1. function connectFriend(friendId,userId,headPicture){
    2.         deletenode();
    3.         //stopRefresh();
    4.         //clearTimeout(over);
    5.         $("chatingeare").style.display = "block";
    6.         $("friendId").value = friendId;
    7.         $("userId").value = userId;
    8.         $("headPicture").value = headPicture;
    9.         pushdown();
    10.         getmessage();
    11.         deletechating();
    12. }

    复制代码

    #p#副标题#e#

    第一个deletenode()是一个函数:

    1. function deletenode(){
    2.         var a = document.getElementById("chatingtext");
    3.         var ul_arr = a.getElementsByTagName("p");
    4.         while(ul_arr.length!=0){
    5.                 a.removeChild(ul_arr[0]);
    6.         }
    7. }
    复制代码

    这个函数主要作用是清除上个与好友聊天的所有信息,因为我们的聊天主要是通过在id为chatingtext下插入<p></p>实现的,因此要清除之前的聊天记录只需要,使用DOM把他下面的所有子节点全部删除。

    这段代码主要是当用户点击另外一个用户的时候会弹出对话框(对话框最初是隐藏的),对话框代码如下:

    1.         <div id="chatingeare" style="display:none;">
    2.                                 <div id="chatingtext">
    3.                                         <div id="refresh" class="node"></div>
    4.                                 </div>
    5.                                 <div>
    6.                                         <form>
    7.                                                 <textarea id="textarea" value=""></textarea><br/>
    8.                                                 <input type="button" onclick="sendmessage()" value="发送"/>
    9.                                                 <input id="friendId" type="hidden" value=""/><input id="userId" type="hidden" value=""/> <input id="headPicture" type="hidden" value=""/>
    10.                                                 <input type="button" onclick="nodisplay()" value="关闭"/>
    11.                                         </form>
    12.                                 </div>
    13.                         </div>
    复制代码

    这段代码,包含了三个hidden的type的input,主要是为了保存js中的变量值。

    这段代码主要为了在js文件中互相传递参数,也就是说connectFriend(friendId,userId,headPicture)函数传入的三个参数,插入到html中input的value中,以后只要js希望得到这个参数就直接可以$(“friendId”).value就可以相应的得到friendId变量。其实这里的话可以设置全局变量,同样可以达到相应的结果。
    接下来我们看pushdown函数,这个函数主要是为了,当用户正在和一个人聊天,而另外一个人却在Q用户的时候,用户可以把当前聊天的用户缩放到工具栏下,而切换与另外一个人聊天。代码如下:

    1. function pushdown(){
    2.         var headPicture = $("headPicture").value;
    3.         var friendId = $("friendId").value;
    4.         var userId = $("userId").value;
    5.         var len = $("newspicture").getElementsByTagName("input").length;
    6.         var count=0;
    7.         for(i=0;i<len;i++){
    8.                 if(friendId ==  $("newspicture").getElementsByTagName("input")[i].value)
    9.                         count++;
    10.         }
    11.         if(count==0){
    12.         res = "<li id='"+friendId+"'><a href='#'  onclick=connectFriend("+friendId+","+userId+","+headPicture+")>"+"<img style='width:20px' src =../imgs/headPicture/"+headPicture+".jpg />"+"</a>&nbsp;&nbsp;&nbsp;"+"<input name=headpicture value='"+friendId+"'type='hidden'></li>"
    13.         var newNode = document.createElement("span");
    14.         newNode.innerHTML = res;
    15.         $("newspicture").appendChild(newNode);
    16.         }
    17. }

    复制代码

    #p#副标题#e#

    其中的前三行就是获取前面的三个变量,然后len是获取当前工具栏下的所有用户,主要是为了避免一个用户多次被缩放到工具栏下面,这里实现了一个判断,就是如果工具栏存在改用户,则不会插入用户头像,如果该工具栏下没有改用户则执行插入用户头像。
    然后就是getmessage()函数:

    1. function getmessage(){
    2.         var friendId = $("friendId").value;
    3.         var userId = $("userId").value;
    4.         var url = "../ajax/getchating.php";
    5.         var myAjax = new Ajax.Request(
    6.         url,
    7.         {
    8.             method:"post",
    9.                          parameters: {
    10.                     friendId : friendId,
    11.                                         userId   : userId
    12.             },
    13.             onError: function (request){
    14.                 alert("请求方法发生错误!"+request.statusText);
    15.             },
    16.             onComplete: function (request){
    17.                 var res = request.responseText;
    18.                                 if(friendContext != res){
    19.                                         var newNode = document.createElement("p");
    20.                                         newNode.innerHTML = res;
    21.                                         newNode.className = "node";
    22.                                         $("chatingtext").appendChild(newNode);
    23.                                 }
    24.                                 friendContext = res;
    25.             },
    26.             asynchronous:true
    27.         });
    28.         t = setTimeout(getmessage,2000);
    29.         //addnewnode();
    30. }
    复制代码

    代码主要是通过ajax实现的,前面两行代码同样是获取userId、friendId变量。url主要是链接到相应的PHP处理文件,然后就是我们熟悉的ajax。接下来我们去查看一个getchating.php看一下主要是如何处理获取聊天信息功能的。

    1.     $friendId = $_POST['friendId'];
    2.         $userId = $_POST['userId'];
    3.  
    4.     if (isset($friendId) && $friendId != 0 && isset($userId) && $userId != 0){
    5.                         if(exist_chating($userId, $friendId)){
    6.                                 $id = exist_chating($userId, $friendId);       
    7.                                 $user  = get_user($friendId);
    8.                                 $userName = $user->get_userName();
    9.                                 $chating = get_chating($id);
    10.                                 $contentToPerson = $chating->get_contentToPerson();
    11.                                 if($contentToPerson != 1){
    12.                                         echo "<span style='color:blue''>$userName:</span> $contentToPerson";
    13.                                 }
    14.                                 else
    15.                                         echo " ";
    16.                         }
    17.                         if(exist_chating($friendId,$userId)){
    18.                                 $id = exist_chating($friendId,$userId);       
    19.                                 $user  = get_user($friendId);
    20.                                 $userName = $user->get_userName();
    21.                                 $chating = get_chating($id);
    22.                                 $contentToPerson = $chating->get_contentToFriend();
    23.                                 if($contentToPerson != 1){
    24.                                         echo "<span style='color:blue''>$userName:</span> $contentToPerson";
    25.                                 }
    26.                                 else
    27.                                         echo " ";
    28.                         }
    29.                         else{
    30.                                 echo "";
    31.                         }
    32.         }

    复制代码

    #p#副标题#e#

    前面两行代码是,获取ajax传入的两个变量,if条件主要是判断改id是否有效,如果就是主题代码:第一个条件判断该聊天是否已经建立,如果建立了,则直接返回用户输入的信息。第二个同样是判断是否已经建立。建立以后从数据库读取信息content,然后返回信息的html内容。Ajax得到返回的html代码,然后判断该代码是否和之前读取的代码相同,如果代码相同表示好友没有发送新消息给用户,那么我们在对话框中就不需要插入新的信息,如果不存在则插入本条返回的html信息,直接显示在对话框中。

    1.             onComplete: function (request){
    2.                 var res = request.responseText;
    3.                                 if(friendContext != res){
    4.                                         var newNode = document.createElement("p");
    5.                                         newNode.innerHTML = res;
    6.                                         newNode.className = "node";
    7.                                         $("chatingtext").appendChild(newNode);
    8.                                 }
    9.                                 friendContext = res;
    10.             },
    复制代码

    这段就是处理返回的结果代码,friendContext就是前一次获取的数据库中的好友信息。res就是获取的最新信息,如果两者不相同,则执行插入操作。如果两者相同则不需要做任何操作。

    1.         t = setTimeout(getmessage,2000);
    复制代码

    最后一段代码就是,每隔2秒钟获取数据库中的好友发给user的信息。
    到这里为止我们就讲解了如何每隔2秒钟,获取是否有好友发送信息给自己。如果有就会插入在聊天对话框中,这样就可以实现,friend发送的消息,在本地可以实时的查看,而不需要刷新。
       接下来,我们讲解如何发送信息给好友:

    1.                                         <form>
    2.                                                 <textarea id="textarea" value=""></textarea><br/>
    3.                                                 <input type="button" onclick="sendmessage()" value="发送"/>
    4.                                                 <input id="friendId" type="hidden" value=""/><input id="userId" type="hidden" value=""/> <input id="headPicture" type="hidden" value=""/>
    5.                                                 <input type="button" onclick="nodisplay()" value="关闭"/>
    6.                                         </form>
    复制代码

    代码里面有一个发送的content和发送的用户,以及发送给谁的用户的value值,并且出了content其他的都是隐藏的,这个在前面的connectFriend函数里面已经讲解过,这里不在累赘。代码中的一个value值为“发送”的button,当用户点击发送的时候会触发sendmessage函数,下面我们来简单的看一下这个函数:

    1. function sendmessage(){
    2.         var friendId = $("friendId").value;
    3.         var userId = $("userId").value;
    4.         var content = $("textarea").value;
    5.         var url = "../ajax/chating.php";
    6.         var myAjax = new Ajax.Request(
    7.         url,
    8.         {
    9.             method:"post",
    10.                          parameters: {
    11.                     friendId : friendId,
    12.                                         userId   : userId,
    13.                                         content  : content
    14.             },
    15.             onError: function (request){
    16.                 alert("请求方法发生错误!"+request.statusText);
    17.             },
    18.             onComplete: function (request){
    19.                 var res = request.responseText;
    20.                 var newNode = document.createElement("p");
    21.                                 newNode.innerHTML = res;
    22.                                 newNode.className = "node";
    23.                                 $("chatingtext").appendChild(newNode);
    24.             },
    25.             asynchronous:true
    26.         });
    27.                 //t = setTimeout(getmessage, 5);
    28.                 //refresh(friendId,userId);
    29.                 //getmessage(friendId,userId);
    30. }
    复制代码

    前三行代码主要是获取三个变量值。url主要是链接处理文件PHP。接下来是Ajax,我们看一下chating.php处理的功能:

    1.     $friendId = $_POST['friendId'];
    2.         $userId = $_POST['userId'];
    3.         $content  = $_POST['content'];
    4.         $content = iconv('UTF-8','gb2312',$content);
    5.  
    6.     if (isset($friendId) && $friendId != 0 && isset($userId) && $userId != 0){
    7.     if (exist_chating($userId, $friendId)) {       
    8.             $id =exist_chating($userId, $friendId);
    9.                 $user  = get_user($userId);
    10.                 $userName = $user->get_userName();
    11.                 update_contentToFriend($id, $content);
    12.                 $chating = get_chating($id);
    13.                 $contentToFriend = $chating->get_contentToFriend();
    14.                 echo "<span style='color:red'>$userName:</span> $contentToFriend";
    15.     }
    16.         else if(exist_chating($friendId,$userId )){
    17.                 $id =exist_chating($friendId,$userId );
    18.                 $user  = get_user($userId);
    19.                 $userName = $user->get_userName();
    20.                 update_contentToPerson($id, $content);
    21.                 $chating = get_chating($id);
    22.                 $contentToPerson= $chating->get_contentToPerson();
    23.                 echo "<span style='color:red'>$userName:</span> $contentToPerson";
    24.         }
    25.         else{
    26.                 $id = save_chating($userId, $friendId, $content, "1");
    27.                 $user  = get_user($userId);
    28.                 $userName = $user->get_userName();
    29.                 $chating = get_chating($id);
    30.                 $contentToFriend = $chating->get_contentToFriend();
    31.                 echo "<div><span style='color:red''>$userName:</span> $contentToFriend</div>";
    32.         }

    复制代码

    #p#副标题#e#

    前四行是获取Ajax传入的三个变量,然后判断两个id是否合法。
    接下来三个if判断函数,第一个判断当前是否已经在数据库建立了两者的聊天记录,第二个判断和第一个一样,主要是为了防止以下这种情况的发生:



    其实这两者的关系是一样的,因此只需要存储一

    种,也就是先发起对话的人为user,回复信息的

    人为Friend。
    如果数据库没有建立二者的聊天记录,在在数据库插入一段新的记录,并返回聊天信息。

    1.                         var newNode = document.createElement("p");
    2.                                         newNode.innerHTML = res;
    3.                                         newNode.className = "node";
    4.                                         $("chatingtext").appendChild(newNode);
    复制代码

    Ajax得到返回结果直接插入在html中,从而就可以实现,自己发送的消息自己可以查看。

    1. function bindUI(){
    2.         getothermessage();
    3. }
    4.  
    5. function getothermessage(){
    6.         var userId = $("userId").value;
    7.         var url = "../ajax/getothermessage.php"
    8.         var myAjax = new Ajax.Request(
    9.         url,
    10.         {
    11.             method:"post",
    12.                          parameters: {
    13.                     userId:userId
    14.             },
    15.             onError: function (request){
    16.                 alert("请求方法发生错误!"+request.statusText);
    17.             },
    18.             onComplete: function (request){
    19.                 var res = request.responseText;
    20.                                 if(res.indexOf("newmessage") != -1){
    21.                                         play_click("../imgs/msg.wav");
    22.                                 }
    23.             },
    24.             asynchronous:true
    25.         });
    26. }
    27.  
    28. function play_click(url){  
    29.     var div = $('music');  
    30.      div.innerHTML = '<embed src="'+url+'" loop="0" autostart="true" hidden="true"></embed>';  
    31.      var emb = document.getElementsByTagName('EMBED')[0];  
    32.      if (emb) {  
    33.         setTimeout(function(){div.innerHTML='';},1000);  
    34.     }  
    35. }
    36.  
    37. document.observe('dom:loaded', bindUI);
    复制代码

    还有就是一些辅助的信息功能,比如说getothermessage(),就是获取当前正在和好友聊天,是否还有其他用户发送消息给我。Play_click()主要是声音提示,当有新的消息时候会有声音提示用户您有新的消息。
    最后就是用户聊天结束以后,建立的聊天要从数据库删除,处理函数主要是:

    deletechating.php同样的是PHP处理文件,主要是在数据库删除用户聊天记录。
     


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多