首页 » PHP和MySQL Web开发(原书第4版) » PHP和MySQL Web开发(原书第4版)全文在线阅读

《PHP和MySQL Web开发(原书第4版)》31.5 查看文章的树形结构

关灯直达底部

接下来,我们需要一种方法将信息从数据库中取出,并将其在树形结构中表示出来。我们在主页面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/']);函数的调用,由它实际产生要显示的文章树形结构。