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 相关文章推荐
基于mysql的论坛(5)
Oct 09 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
Nov 24 PHP
PHP源代码数组统计count分析
Aug 02 PHP
基于php下载文件的详解
Jun 02 PHP
解析php函数method_exists()与is_callable()的区别
Jun 21 PHP
PHP使用array_fill定义多维数组的方法
Mar 18 PHP
PHP网站建设的流程与步骤分享
Sep 25 PHP
Yii2简单实现给表单添加验证码的方法
Jul 18 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
Nov 04 PHP
php类自动装载、链式操作、魔术方法实现代码
Jul 23 PHP
php获取小程序码的实现代码(B类接口)
Jun 13 PHP
PHP文件操作简单介绍及函数汇总
Dec 11 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
基于Zookeeper的使用详解
2013/05/02 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
2014/06/13 PHP
CI操作cookie的方法分析(基于helper类库)
2016/03/28 PHP
JAVASCRIPT对象及属性
2007/02/13 Javascript
写自已的js类库需要的核心代码
2012/07/16 Javascript
判断输入是否为空,获得输入类型的JS代码
2013/10/30 Javascript
JavaScript用JQuery呼叫Server端方法示例代码
2014/09/03 Javascript
js实现文字闪烁特效的方法
2015/12/17 Javascript
JavaScript File分段上传
2016/03/10 Javascript
js运动事件函数详解
2016/10/21 Javascript
vue日期组件 支持vue1.0和2.0
2017/01/09 Javascript
BootStrap表单验证实例代码
2017/01/13 Javascript
JS实现的简单标签点击切换功能示例
2017/09/21 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
分享5个好用的javascript文件上传插件
2018/09/16 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
微信小程序实现列表左右滑动
2020/11/19 Javascript
Python下使用Psyco模块优化运行速度
2015/04/05 Python
Python实现控制台进度条功能
2016/01/04 Python
python如何生成网页验证码
2018/07/28 Python
Python3基础教程之递归函数简单示例
2019/06/07 Python
python序列类型种类详解
2020/02/26 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
新奇的小玩意:IWOOT
2016/07/21 全球购物
西班牙英格列斯百货英国官网:El Corte Inglés英国
2017/10/30 全球购物
社区党务公开实施方案
2014/03/18 职场文书
党的群众路线对照检查材料思想汇报(学校)
2014/10/04 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
英语复习计划
2015/01/19 职场文书
小学生2015教师节演讲稿
2015/03/19 职场文书
签订劳动合同通知书
2015/04/16 职场文书
留学文书中的个人陈述,应该注意哪些问题?
2019/08/23 职场文书
为什么你写的height:100%不起作用
2021/05/10 HTML / CSS
使用python创建股票的时间序列可视化分析
2022/03/03 Python