接下来,我们需要一种方法将信息从数据库中取出,并将其在树形结构中表示出来。我们在主页面index.php中完成这项工作。为了将这个过程解释得更加清楚,我们通过文章粘贴脚本程序new_post.php和store_new_post.php输入了一些样本帖子。我们将在下一节介绍这两个程序。
这里,我们首先讨论文章列表,因为它是整个站点的主体。然后其他内容就容易理解了。
如图31-4所示的是用户将看到的该站点初始的文章视图。
图 31-4 文章列表的初始视图显示了在折叠表单中的文章我们这里看到的都是最初的文章,它们都没有回复文章;它们都是某特定主题的第一篇文章。
在这个例子中,还可以看到有很多选项。有一个菜单栏,我们可以用它来添加一篇新文章以及展开或折叠文章的视图。
为了理解这一点,请看这些发表的文章。其中有一些文章前面有“+”号,这表示这些文章已经被回复过。如果要查看特定文章的回复,可以点击该加号标志。如图31-5所示的就是点击这些符号产生的一个结果。
图 31-5 关于PHP持续性的讨论话题已被展开可以看到,点击加号后会显示出第一篇文章的回复。而加号则变成了减号。如果我们再点击它,在这个话题里的所有文章都将会折叠起来,又返回至初始视图。
可以看到,其中的一篇回复前面也有个加号。这表示这篇回复也有回复。如此重复操作,可以一直点击下去,通过点击相应的加号来查看每篇回复。
在菜单栏中,有两个菜单选项,Expand和Collapse,分别为展开和折叠所有可能的话题。点击Expand按钮的结果如图31-6所示。
图 31-6 所有话题都已被展开如果你仔细查看图31-5和图31-6,可以看到我们在命令行中将一些参数传回了index.php。在图31-5中,URL框显示了如下所示字符串:
http://localhost/phpmysql4e/chapter31/index.php?expand=2#2
以上脚本将上面这行解释为“展开postid为2的节点”。“#”号仅是个HTML标记,用来滚动页面直到刚才展开的那个节点。
http://localhost/phpmysql4e/chapter31/index.php?expand=all
在图31-6中,URL是点击/"Expand/"按钮将传递一个值为all的expand参数。
31.5.1 展开和折叠
要了解如何创建文章视图,让我们来研究index.php脚本,如程序清单31-2所示。
程序清单31-2 index.php——在应用程序主页面创建文章视图的脚本
<?php
include(/'include_fns.php/');
session_start;
//check if we have created our session variable
if(!isset($_SESSION[/'expanded/'])){
$_SESSION[/'expanded/']=array;
}
//check if an expand button was pressed
//expand might equal/'all/'or a postid or not be set
if(isset($_GET[/'expand/'])){
if($_GET[/'expand/']==/'all/'){
expand_all($_SESSION[/'expanded/']);
}else{
$_SESSION[/'expanded/'][$_GET[/'expand/']]=true;
}
}
//check if a collapse button was pressed
//collapse might equal all or a postid or not be set
if(isset($_GET[/'collapse/'])){
if($_GET[/'collapse/']==/'all/'){
$_SESSION[/'expanded/']=array;
}else{
unset($_SESSION[/'expanded/'][$_GET[/'collapse/']]);
}
}
do_html_header(/'Discussion Posts/');
display_index_toolbar;
//display the tree view of conversations
display_tree($_SESSION[/'expanded/']);
do_html_footer;
?>
以上脚本使用3个变量来实现其功能。它们是:
■会话变量expanded,用来记录那些已经被展开的记录。该变量可以在不同的视图之间使用,因此我们可展开多个话题。该变量是一个数组,它包含了与那些需要展开并显示其回复文章相关的postid数组。
■参数expand,告诉脚本哪个新话题需要展开。
■参数collapse,通知脚本哪个话题需要折叠。
当点击加号或减号,或者点击Expand或Collapse按钮时,它们将再次调用index.php脚本,不过将带有新的参数expand和collapse。我们使用expanded变量在页面间记录哪些话题在任何给定的视图中应该展开。
该脚本以初始化一个会话开始,并增加expanded变量作为会话变量,如果这个操作还没有完成的话。之后,该脚本将检查是否传递了expand或collapse参数,并相应地修改expanded数组。请看以下关于expand参数的代码:
if(isset($_GET[/'expand/'])){
if($_GET[/'expand/']==/'all/'){
expand_all($_SESSION[/'expanded/']);
}else{
$_SESSION[/'expanded/'][$_GET[/'expand/']]=true;
}
}
如果点击了Expand按钮,该操作将调用expand_all函数,这样所有有回复的话题都将加入到expanded数组中(稍后将详细介绍)。
如果想要扩展特定话题,可以通过expand变量传递一个postid。因此,我们可以在expanded数组中增加一条新记录来反映它。
expand_all函数如程序清单31-3所示。
程序清单31-3 discussion_fns.php函数库中的expand_all函数——对$expanded数组进行操作以展开论坛中所有话题
function expand_all(&$expanded){
//mark all threads with children as to be shown expanded
$conn=db_connect;
$query=/"select postid from header where children=1/";
$result=$conn->query($query);
$num=$result->num_rows;
for($i=0;$i<$num;$i++){
$this_row=$result->fetch_row;
$expanded[$this_row[0]]=true;
}
}
该函数运行一个数据库查询语句来找出论坛中哪些话题有回复,如下所示:
select postid from header where children=1
每一篇返回的文章都将被添加到expanded数组中。我们运行查询语句是为了节省时间。也可以简单地将所有文章加入到expanded列表中,但是尝试处理那些不存在的回复相当浪费时间。
折叠文章节点的操作与此非常相似,不过是以相反的方法进行的,如下所示:
if(isset($_GET[/'collapse/'])){
if($_GET[/'collapse/']==/'all/'){
$_SESSION[/'expanded/']=array;
}else{
unset($_SESSION[/'expanded/'][$_GET[/'collapse/']]);
}
}
可以通过重置该数组,从该数组中删除所有条目。如果整个页面都需要折叠,就删除需要折叠的话题或重置整个数组。
以上所有这些操作都只是预处理,由此我们可以知道哪些文章应该显示出来而哪些不应该显示。该脚本的主要部分是对display_tree($_SESSION[/'expanded/']);函数的调用,由它实际产生要显示的文章树形结构。