此为php版本的无刷新聊天程序源代码,支持html web编辑器。此例子也可以作为mssql存储过程使用的示例,如php调用mssql的存储过程,php获取mssql数据库的输出参数。
下面只列出php版本的代码,js类库及说明请看下面asp.net版本的,asp版本也在下面。
asp.net版本
ajax+asp.net+mssql无刷新聊天室asp版本
ajax+asp+mssql无刷新聊天室
不过有个小问题,就是firefox下如果使用快捷键ctrl+enter发送信息时,如果不延时调用发送函数,会弹出ff的下载对话框,奇怪。谁能解决这个问题,100分归他,其他100分当作散分。【等级不够,明天再加100】if(e.ctrlKey&&e.keyCode==13){
          e.preventDefault();
          e.stopPropagation();
          setTimeout("Showbo.Chat.send()",50);//在ff中马上使用alert提示时尽然弹出下载工具,奇怪.
          return false;}
       },false);
为了加快速度,使用了存储过程。
要使用不同的动态页面,只需要更改lib.js文件中RequstUrl变量的值即可。
完整示例下载效果如下内容长度限制,所以就不贴出所有的代码了,要看全部代码请下载示例或者查看下面这篇文章
ajax+asp.net+mssql无刷新聊天室op.php
<?php
$db="chatdb";$uid="sa";$pwd="";$server=".";
class ajax{
function js($v){
return str_replace("'","\\'",$v);
}
function Login(){//用户登录
        global $db,$uid,$pwd,$server;
$rStr="";
$Username=$_POST["nn"];
if(empty($Username))return "success:false,err:'昵称不能为空!'";
if(strlen($Username)>20)return "success:false,err:'昵称不能超过20个字符!'";
$userId="";$key="";
$cn=mssql_connect($server,$uid,$pwd);
mssql_select_db($db,$cn);
$stmt=mssql_init("ajaxLogin",$cn);
mssql_bind($stmt,"@username",$Username,SQLVARCHAR,false,false);
mssql_bind($stmt,"@userid",$userId,SQLVARCHAR,true,false);
mssql_bind($stmt,"@userkey",$key,SQLVARCHAR,true,false);
mssql_execute($stmt,true);
mssql_close($cn);
$userId=trim($userId);$key=trim($key);
if($userId=="-1")$rStr="success:false,err:'发生错误,请稍后再试!'";
else if($userId=="0")$rStr="success:false,err:'已经存在此用户昵称,请修改您的昵称!'";
else $rStr="success:true,UserId:'" .$userId. "',Key:'".$key."'";
return $rStr;
}
function Logout(){//注销用户
global $db,$uid,$pwd,$server;
$rStr="";$userId=$_POST["uid"];$key=$_POST["key"];
if(empty($userId)||empty($key))return "success:false,err:'用户信息丢失!'";
$cn=mssql_connect($server,$uid,$pwd);
mssql_select_db($db,$cn);
$stmt=mssql_init("ajaxLogout",$cn);
mssql_bind($stmt,"@userid",$userId,SQLVARCHAR,false,false);
mssql_bind($stmt,"@userkey",$key,SQLVARCHAR,false,false);
mssql_bind($stmt,"@Result",$r,SQLINT1,true,false);
mssql_execute($stmt,true);
mssql_close($cn);
$r=trim($r);
if($r=="0")$rStr="success:false,err:'用户信息不存在!'";
else $rStr="success:true";
return $rStr;
}
function Say(){//发表信息
global $db,$uid,$pwd,$server;
$rStr="";$From=$_POST["from"];$To=$_POST["to"];$key=$_POST["key"];$Msg=$_POST["ct"];
if(empty($From)||empty($key)||empty($To)||empty($Msg))return "success:false,err:'信息传递不完整!'";
$Msg=iconv("utf-8","gb2312",$Msg);//=============注意要解码,并且客户端要使用encodeURI/encodeURIComponent编码,要不发送到服务器端接收会乱码
$cn=mssql_connect($server,$uid,$pwd);
mssql_select_db($db,$cn);
$stmt=mssql_init("ajaxSay",$cn);
mssql_bind($stmt,"@userkey",$key,SQLVARCHAR,false,false);
mssql_bind($stmt,"@from",$From,SQLVARCHAR,false,false);
mssql_bind($stmt,"@to",$To,SQLVARCHAR,false,false);
mssql_bind($stmt,"@msg",$Msg,SQLVARCHAR,false,false);
mssql_bind($stmt,"@Result",$r,SQLINT4,true);
mssql_execute($stmt,true);
mssql_close($cn);
if($r=="0")$rStr="sucess:false,err:'发表失败!\\n原因:接收者已经不存在!'";
else $rStr="success:true";
return $rStr;
}
function ReadUser(){//获取用户列表
global $db,$uid,$pwd,$server;
$rStr="";$userId=$_POST["uid"];
if(empty($userId))return "success:false,err:'用户id丢失!'";
$cn=mssql_connect($server,$uid,$pwd);
mssql_select_db($db,$cn);
$stmt=mssql_init("ajaxReadUser",$cn);
mssql_bind($stmt,"@userid",$userId,SQLVARCHAR,false,false);
$rs=mssql_execute($stmt);
$rNum=mssql_num_rows($rs);
for($i=0;$i<$rNum;$i++){
$row=mssql_fetch_row($rs);
$rStr.=",{id:'" . $row[0] . "',nn:'" . Ajax::Js($row[1]) . "'}";
}
mssql_free_result($rs);
mssql_close($cn);
return "success:true,data:[" . ($rStr == "" ? "" : substr($rStr,1)) . "]";
}
function Read(){//信息列表
global $db,$uid,$pwd,$server;
$rStr="";$userId=$_POST["uid"];$key=$_POST["key"];
if(empty($userId)||empty($key))return "success:false,err:'用户信息丢失!'";
$cn=mssql_connect($server,$uid,$pwd);
mssql_select_db($db,$cn);
$stmt=mssql_init("ajaxRead",$cn);
mssql_bind($stmt,"@userid",$userId,SQLVARCHAR,false,false);
mssql_bind($stmt,"@userkey",$key,SQLVARCHAR,false,false);
$rs=mssql_execute($stmt);
$rNum=mssql_num_rows($rs);
for($i=0;$i<$rNum;$i++){
$row=mssql_fetch_row($rs);
$rStr.=",'".Ajax::js($row[0])."'";
}
mssql_free_result($rs);
mssql_close($cn);
return "success:true,data:[" . ($rStr == "" ? "" : substr($rStr,1)) . "]";
}
}
$Json = "{";
switch ($_POST["op"]){
case "login": $Json .= Ajax::Login(); break;
case "logout": $Json .= Ajax::Logout(); break;
case "readuser": $Json .= Ajax::ReadUser(); break;
case "read":$Json.=Ajax::Read(); break;
case "say": $Json.= Ajax::Say(); break;
default: $Json.= "success:false,err:'参数错误!'"; break;
}
$Json .= "}";header('Content-Type:text/html;charset=GB2312'); //==========注意要设置响应头的编码,要不客户端接收会乱码
echo($Json);
?>

解决方案 »

  1.   

    firefox下如果使用快捷键ctrl+enter发送信息时,如果不延时调用发送函数,会弹出ff的下载对话框,奇怪。 
    这个问题没有人碰到过吗???100分啊,这个问题。。 
      

  2.   


    真没遇见过,不过PHP+MSSQL,还真不用他
      

  3.   


    应该只有 ASP 会这样~好像跟header有关
      

  4.   

    我也是觉得奇怪啊。不想安装mysql了,所以直接用mssql,呵呵~~~
    把问题提取出来,精简一下。编辑器是可编辑的Iframe,不是textarea,在 ie6,safari3.0.4,opera9,谷歌0.4 中都没出现问题,就是在firefox中出现了弹出下载对话框的问题。在发送信息时要检查是否输入内容,所以如果为空时就alert提示信息为空,然后firefox就弹出下载对话框了,不管是ff2还是ff3都存在这个问题。<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>无标题文档</title>
    <style type="text/css">
    #HtmlEditor{border:solid 1px black;margin:100px auto;display:block;width:600px;height:150px;}
    </style>
    </head>
    <body>
    <script type="text/javascript">
    //firefox2.0.0.12  3.0.3
    var IsIE=!!document.all;function send(){
     alert('调用类库函数发送信息!');
    }function setEditable(){
        var editor=IsIE?document.frames["HtmlEditor"]:document.getElementById('HtmlEditor').contentWindow;
        try{
          var doc=editor.document;
          if(doc.body){
            doc.body.style.fontSize='14px';
            doc.body.style.fontFamily="verdana";
            doc.body.style.margin="4px";
          }
          doc.designMode="On";
          if(IsIE)doc.contentEditable="True";
          //==================这里初始化 Showbo.Chat.bd对象
          initEvent(doc,editor);
        }catch(e){alert(e)}
      }
    function initEvent(doc,editor){
         if(IsIE){//=====================IE===================
           doc.onkeydown=function(){
             e=editor.event;//注意这里获取的是iframe中的事件对象         
             if(e.keyCode==13){
                e.returnValue=false;
                e.keyCode=0;
                if(e.ctrlKey){send();return false;}
                //在ie时回车生成<p>,替换为<br>.ff下生成<br>,所以不需要处理回车
            var r=this.selection.createRange();
            r.pasteHTML("<br>");
                r.select();
             }
           }
         }
         else doc.addEventListener('keydown',function(e){
            if(e.ctrlKey&&e.keyCode==13){
              e.preventDefault();
              e.stopPropagation();
    //====================大家可以分别注释下面的句子试试就知道了=============
              send();//在ff中马上使用alert提示时弹出下载工具,奇怪.
              //setTimeout("send()",50);//延时就不会弹出下载工具
              return false;}
           },false);
      };
     // window.onload=setEditable;
    </script>
    <iframe ID="HtmlEditor" name="HtmlEditor" frameborder="0" marginheight="0" marginwidth="0" src="about:blank" onload="setEditable()"></iframe>
    </body>
    </html>
      

  5.   

    很诡异的问题,我也认为ff的bug.
      

  6.   

    FF BUG了就像我做的那个连续播放音乐,用实体数组可以连续播放,用其他方法生存的数组死活都不可以!