thinkPHP实现基于ajax的评论回复功能


Posted in PHP onJune 22, 2018

本文实例讲述了thinkPHP实现基于ajax的评论回复功能。分享给大家供大家参考,具体如下:

控制器代码:

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
  public function index(){
    $num = M('comment')->count(); //获取评论总数
    $this->assign('num',$num);
    $data=array();
    $data=$this->getCommlist();//获取评论列表
    $this->assign("commlist",$data);
    $this->display('index');
  }
  /**
  *添加评论
  */
  public function addComment(){
    $data=array();
    if((isset($_POST["comment"]))&&(!empty($_POST["comment"]))){
      $cm = json_decode($_POST["comment"],true);//通过第二个参数true,将json字符串转化为键值对数组
      $cm['create_time']=date('Y-m-d H:i:s',time());
      $newcm = M('comment');
      $id = $newcm->add($cm);
      $cm["id"] = $id;
      $data = $cm;
      $num = M('comment')->count();//统计评论总数
      $data['num']= $num;
    }else{
      $data["error"] = "0";
    }
    echo json_encode($data);
  }
  /**
  *递归获取评论列表
  */
  protected function getCommlist($parent_id = 0,&$result = array()){
    $arr = M('comment')->where("parent_id = '".$parent_id."'")->order("create_time desc")->select();
    if(empty($arr)){
      return array();
    }
    foreach ($arr as $cm) {
      $thisArr=&$result[];
      $cm["children"] = $this->getCommlist($cm["id"],$thisArr);
      $thisArr = $cm;
    }
    return $result;
  }
}

JavaScript代码:

$(function(){
  //点击提交评论内容
  $('body').delegate('.comment-submit','click',function(){
    var content = $.trim($(this).parent().prev().children("textarea").val());//根据布局结构获取当前评论内容
    $(this).parent().prev().children("textarea").val("");//获取完内容后清空输入框
    if(""==content){
      alert("评论内容不能为空!");
    }else{
      var cmdata = new Object();
      cmdata.parent_id = $(this).attr("parent_id");//上级评论id
      cmdata.content = content;
      cmdata.nickname = "游客";//测试用数据
      cmdata.head_pic = "/Public/images/default.jpg";//测试用数据
      var replyswitch = $(this).attr("replyswitch");//获取回复开关锁属性
      $.ajax({
        type:"POST",
        url:"/index.php/home/index/addComment",
        data:{
          comment:JSON.stringify(cmdata)
        },
        dataType:"json",
        success:function(data){
          if(typeof(data.error)=="undefined"){
            $(".comment-reply").next().remove();//删除已存在的所有回复div
            //更新评论总数
            $(".comment-num").children("span").html(data.num+"条评论");
            //显示新增评论
            var newli = "";
            if(cmdata.parent_id == "0"){
             //发表的是一级评论时,添加到一级ul列表中
             newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);'>回复</a></div></div></div><ul class='children'></ul></li>";
              $(".comment-ul").prepend(newli);
            }else{
             //否则添加到对应的孩子ul列表中
              if('off'==replyswitch){//检验出回复关闭锁存在,即三级评论不再提供回复功能
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'></div></div></div><ul class='children'></ul></li>";
              }else{//二级评论的回复按钮要添加回复关闭锁属性
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);' replyswitch='off' >回复</a></div></div></div><ul class='children'></ul></li>";
              }
              $("li[comment_id='"+data.parent_id+"']").children("ul").prepend(newli);
            }
          }else{
            //有错误信息
            alert(data.error);
          }
        }
      });
    }
  });
  //点击"回复"按钮显示或隐藏回复输入框
  $("body").delegate(".comment-reply","click",function(){
    if($(this).next().length>0){//判断出回复div已经存在,去除掉
      $(this).next().remove();
     }else{//添加回复div
      $(".comment-reply").next().remove();//删除已存在的所有回复div
      //添加当前回复div
      var parent_id = $(this).attr("comment_id");//要回复的评论id
      var divhtml = "";
      if('off'==$(this).attr("replyswitch")){//二级评论回复后三级评论不再提供回复功能,将关闭属性附加到"提交回复"按钮"
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);' replyswitch='off' >提交回复</a></div></div>";
      }else{
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);'>提交回复</a></div></div>";
      }
      $(this).after(divhtml);
     }
  });
})

页面样式代码:

.comment-filed{
  width:640px;
  margin:0 auto;
}
.comment-num{
  text-align: right;
  font-size:14px;
}
.div-txt-submit{
  text-align:right;
  margin-top:8px;
}
.comment-submit{
  background-color:#63B8FF;
  margin-top:15px;
  text-decoration:none;
  color:#fff;
  padding:5px;
  font-size:14px;
}
.txt-commit{
  border:1px solid blue;
  width:620px;
  height: 60px;
  padding: 10px;
}
.txt-reply{
  width: 100%;
  height: 60px;
}
.comment-filed-list{
  margin-top:20px;
}
.comment-list{
  margin-top:2px;
  width:herit;
  height:50px;
  border-top:1px solid gray;
}
.comment-ul{
  list-style:none;
  padding-left:0;
}
.head-pic{
  width:40px;
  height:40px;
}
.cm{
  position:relative;
  top:0px;
  left:40px;
  top:-40px;
  width:600px;
}
.cm-header{
  padding-left:5px;
}
.cm-content{
  padding-left:5px;
}
.cm-footer{
  padding-bottom:15px;
  text-align:right;
  border-bottom: 1px dotted #CCC;
}
.comment-reply{
  text-decoration:none;
  color:gray;
  font-size: 14px;
}
.children{
  list-style:none;
  background-color:#FAFAFA;
  padding-left:0;
  margin-left:40px;
}
.children-cm{
  position:relative;
  left:40px;
  top:-40px;
  width:90%;
}

页面布局代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>php评论及回复功能</title>
  <link rel="stylesheet" type="text/css" href="/Public/css/comment.css" rel="external nofollow" >
  <script type="text/javascript" src="/Public/js/jquery-1.11.3.min.js" ></script>
  <script type="text/javascript" src="/Public/js/comment.js" ></script>
</head>
<body>
<div class="comment-filed">
 <!--发表评论区begin-->
 <div>
  <div class="comment-num">
    <span>{$num}条评论</span>
  </div>
  <div>
    <div>
    <textarea class="txt-commit" replyid="0"></textarea>
    </div>
    <div class="div-txt-submit">
      <a class="comment-submit" parent_id="0" style="" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><span style=''>发表评论</span></a>
    </div>
  </div>
 </div>
 <!--发表评论区end-->
 <!--评论列表显示区begin-->
  <!-- {$commentlist} -->
  <div class="comment-filed-list" >
    <div><span>全部评论</span></div>
    <div class="comment-list" >
      <!--一级评论列表begin-->
      <ul class="comment-ul">
        <volist name="commlist" id="data">
          <li comment_id="{$data.id}">
          <div >
            <div>
              <img class="head-pic" src="{$data.head_pic}" alt="">
            </div>
            <div class="cm">
              <div class="cm-header">
              <span>{$data.nickname}</span>
              <span>{$data.create_time}</span>
              </div>
              <div class="cm-content">
                <p>
                  {$data.content}
                </p>
              </div>
              <div class="cm-footer">
                <a class="comment-reply" comment_id="{$data.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
              </div>
            </div>
          </div>
          <!--二级评论begin-->
          <ul class="children">
            <volist name="data.children" id="child" >
            <li comment_id="{$child.id}">
              <div >
                <div>
                  <img class="head-pic" src="{$child.head_pic}" alt="">
                </div>
                <div class="children-cm">
                  <div class="cm-header">
                  <span>{$child.nickname}</span>
                  <span>{$child.create_time}</span>
                  </div>
                  <div class="cm-content">
                    <p>
                      {$child.content}
                    </p>
                  </div>
                  <div class="cm-footer">
                    <a class="comment-reply" replyswitch="off" comment_id="{$child.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
                  </div>
                </div>
              </div>
              <!--三级评论begin-->
              <ul class="children">
                <volist name="child.children" id="grandson" >
                <li comment_id="{$grandson.id}">
                  <div >
                    <div>
                      <img class="head-pic" src="{$grandson.head_pic}" alt="">
                    </div>
                    <div class="children-cm">
                      <div class="cm-header">
                      <span>{$grandson.nickname}</span>
                      <span>{$grandson.create_time}</span>
                      </div>
                      <div class="cm-content">
                        <p>
                          {$grandson.content}
                        </p>
                      </div>
                      <div class="cm-footer">
                        <!-- <a class="comment-reply" comment_id="1" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a> -->
                      </div>
                    </div>
                  </div>
                </li>
                </volist>
              </ul>
              <!--三级评论end-->
            </li>
            </volist>
          </ul>
          <!--二级评论end-->
        </li>
        </volist>
      </ul>
      <!--一级评论列表end-->
    </div>
  </div>
 <!--评论列表显示区end-->
</div>
</body>
</html>

sql语句:

DROP TABLE IF EXISTS `t_comment`;
CREATE TABLE `t_comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
 `parent_id` int(11) NOT NULL COMMENT '上级评论id,若是一级评论则为0',
 `nickname` varchar(100) DEFAULT NULL COMMENT '评论人昵称',
 `head_pic` varchar(400) DEFAULT NULL COMMENT '评论人头像',
 `content` text COMMENT '评论内容',
 `create_time` datetime DEFAULT NULL COMMENT '评论或回复发表时间',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=148 DEFAULT CHARSET=utf8;

页面布局少一个jquery.js请自行加上。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
使用sockets:从新闻组中获取文章(一)
Oct 09 PHP
php获取mysql版本的几种方法小结
Mar 25 PHP
Windows下安装Memcached的步骤说明
Apr 25 PHP
PHP跳转页面的几种实现方法详解
Jun 08 PHP
php实现图片上传时添加文字和图片水印技巧
Apr 18 PHP
PHP的AES加密算法完整实例
Jul 20 PHP
php利用gd库为图片添加水印
Nov 09 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
May 29 PHP
详解Yii2 之 生成 URL 的方法
Jun 16 PHP
基于Laravel实现的用户动态模块开发
Sep 21 PHP
在Laravel5.6中使用Swoole的协程数据库查询
Jun 15 PHP
PHP中md5()函数的用法讲解
Mar 30 PHP
php strftime函数的详细用法
Jun 21 #PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 #PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
Jun 20 #PHP
thinkPHP框架实现的短信接口验证码功能示例
Jun 20 #PHP
thinkPHP3.2.2框架行为扩展及demo示例
Jun 19 #PHP
Laravel框架实现的记录SQL日志功能示例
Jun 19 #PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
Jun 19 #PHP
You might like
PHP下用rmdir实现删除目录的三种方法小结
2008/04/20 PHP
PHP 简易输出CSV表格文件的方法详解
2013/06/20 PHP
php防止伪造的数据从URL提交方法
2014/06/27 PHP
本地计算机无法启动Apache故障处理
2014/08/08 PHP
CI框架的安全性分析
2016/05/18 PHP
PHP实现的文件上传类与用法详解
2017/07/05 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
PHP设计模式之观察者模式定义与用法分析
2019/04/04 PHP
jQuery.Validate 使用笔记(jQuery Validation范例 )
2010/06/25 Javascript
JavaScript定义类和对象的方法
2014/11/26 Javascript
详解Angularjs filter过滤器
2016/02/06 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
iview Upload组件多个文件上传的示例代码
2018/09/30 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
JS判断数组里是否有重复元素的方法小结
2019/05/21 Javascript
vue axios重复点击取消上一次请求封装的方法
2019/06/19 Javascript
JavaScript实现英语单词题库
2019/12/24 Javascript
[59:15]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.20
2020/11/20 DOTA
跟老齐学Python之不要红头文件(2)
2014/09/28 Python
python处理multipart/form-data的请求方法
2018/12/26 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
2019/03/14 Python
用Python获取摄像头并实时控制人脸的实现示例
2019/07/11 Python
使用APScheduler3.0.1 实现定时任务的方法
2019/07/22 Python
详解Python绘图Turtle库
2019/10/12 Python
如何基于python实现不邻接植花
2020/05/01 Python
python爬虫筛选工作实例讲解
2020/11/23 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
2020/11/29 Python
美国最大的珠宝首饰网上商城:Jewelry.com
2016/07/22 全球购物
什么叫应用程序域?什么是托管代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
2012/05/23 面试题
毕业生的自我评价范文
2013/12/31 职场文书
化工操作工岗位职责
2014/04/29 职场文书
会计系毕业求职信
2014/08/07 职场文书
留学推荐信(中英文版)
2015/03/26 职场文书
关于童年的读书笔记
2015/06/26 职场文书
新学期家长寄语2016
2015/12/03 职场文书
vue生命周期钩子函数以及触发时机
2022/04/26 Vue.js