ThinkPHP视图模型实现二级嵌套评论的查询

作者:袖梨 2022-06-25

QQ截图20140317131849

现正在编写一个学习网站项目用于参加全国中小学电脑制作活动,使用ThinkPHP框架
该项目要实现二级嵌套评论,pid为0的为一级评论,否则为二级评论,二级评论为一级评论的子评论。

最初设想是使用ThinkPHP的关联模型,该模型代码( 释义请查阅ThinkPHP相关文档)如下:

 代码如下 复制代码
class ArticleCommentModel extends RelationModel {
 protected $_link = array(
  'User'=>array('mapping_type' => BELONGS_TO,
   'foreign_key' => 'uid',
   'mapping_fields' => 'id,username,email',
   'mapping_name' => 'user',
   ),
  'Article' => array('mapping_type' => BELONGS_TO,
   'foreign_key' => 'aid',
   'mapping_fields' => 'id,res,gpid,gdid,sid,cid,desc,title',
   'mapping_name' => 'article',
   ),
  'ArticleComment'=>array(
   'mapping_type'=>HAS_MANY,
   'foreign_key'=>'id',
   'parent_key'=>'pid',
   'condition'=>'pid!=0',
   'mapping_name' => 'comments',
   ),
  'ArticleApplaud'=>array(
   'mapping_type'=>HAS_MANY,
   'foreign_key'=>'cid',
   'parent_key'=>'id',
   'mapping_name' => 'applaud',
   ),
  );
}

  www.111com.net

?>

该模型可以查询出评论,以及评论相关的信息,如用户信息,评论文章信息,赞信息。

但是由于关联模型查询原理是根据声明的外键来对对应表再进行查询,假使我做的评论分页,一次显示十条评论,一条评论下面最多一次显示十条子评论,先要查询出一级评论,再根据记录再查询用户信息、文章信息、字评论等等,显示一次评论,就要有十几条查询。

效率实在是太低,个人认为,关联模型最佳适于数据库CURD(增删改查)当中的增删改。

于是放弃这个想法,想到还可以用视图模型。遂创建一个视图模型,代码(释义同样请查阅ThinkPHP相关文档)如下:

 代码如下 复制代码

class CommentViewModel extends ViewModel {
 public $viewFields = array(
  'ArticleComment' => array('id','uid', 'aid', 'pid', 'comment', 'ctime'),
  'User' => array('username', 'password', 'email','_on' => 'User.id=ArticleComment.uid', '_type' => "LEFT"),
  'UserInfo' => array('name', 'sex', 'age', 'mobile', 'site', 'address', 'zip', 'intro', '_on' => 'UserInfo.uid=ArticleComment.uid', '_type' => "LEFT"),
  );
}

?>

上述代码还未写出文章相应信息的查询(如有需要增加即可)。查询代码如下:

 代码如下 复制代码

$article = D('CommentView'); //实例化Comment视图模型
$articleComments = $article -> where(array('aid' => $aid, 'pid' => 0)) -> limit(10) -> select(); //将一级评论查询出来 www.111com.net
foreach($articleComments as $comment) {
 $comments[$comment['id']] = $comment; //将查询出来的一级评论按id赋给comments数组
}
$commentID = array_keys($comments); //取出一级评论的id,为下面查询对应的二级评论做准备
if (!empty($commentID)) {
 foreach($commentID as $id) {
  $sqlArray[] = 'pid=' . $id; //生成查询二级评论所用条件数组
 }
 $sql = implode(' OR ', $sqlArray); //将数组连接,生成对应的SQL条件语句
 $articleComments = $article -> where($sql) -> limit(10) -> select(); //查询对应二级评论
 foreach($articleComments as $comment) {
  $comments[$comment['pid']]['comments'][] = $comment; //按树形排列评论
 }
}
$this -> assign('comments', $comments);

原理根据注释很好理解。

1.先查询出pid为0的评论(即为一级评论)

2.将一级评论的评论ID记录下来,生成SQL条件子句

3.使用生成的条件字句进行查询,查询出之前查询出来的一级评论下面的二级评论

4.将查询出来的代码按树形数组格式进行处理,生成comments变量,赋给模板显示

该方法只查询了两次数据库,效率得到了大大的提高。

如果想要做到多级评论,可以再加一个level字段,进行相应的处理,这里不再赘述,读者可以自行尝试。

最终效果:

QQ截图20140317133836

 

相关文章

精彩推荐