当前位置: 首页 > 图文教程 > 网络编程 > ASP > 教大家如何利用ASP打造网站论坛DIY(1)

ASP
ASP基础讲座(下)
解决IIS5 HTTP500内部错误
ASP 3.0高级编程(四十六)
ASP 3.0高级编程(四十五)
ASP 3.0高级编程(四十四)
ASP 3.0高级编程(四十三)
ASP 3.0高级编程(四十二)
ASP 3.0高级编程(四十一)
ASP 3.0高级编程(三十九)
ASP 3.0高级编程(三十八)
ASP 3.0高级编程(三十七)
ASP 3.0高级编程(三十六)
ASP 3.0高级编程(三十五)
ASP 3.0高级编程(三十四)
ASP 3.0高级编程(三十三)
ASP 3.0高级编程(三十二)
ASP 3.0高级编程(三十一)
ASP错误代码说明
jscript错误代码及相应解释大全
ASP错误处理

教大家如何利用ASP打造网站论坛DIY(1)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 139 ::
收藏到网摘: n/a

前言:现在网上的论坛到处都有,但不知您是否遇到过这样的情况:在杂乱无章的讨论信息中来寻找自己想要的内容,是一件很费费时费力的事情,到后来,您就都不想去看什么论坛了。那么我们能不能对自己网站论坛的内容增加审核功能呢?即所有网友发到论坛的文章,并不立即被显示出来,必须经过站长或者版主审阅之后,认为有价值,有必要推荐给其它网友的,就发表出来。否则就删掉了,免得浪费空间,搞得有点像精华区的意味,这样你的论坛比起一般的论坛来,能够提供给为明确有益的内容。放到你的网站上,应该能够吸引更多的网友来访问。这个设想当然可以实现,下面我就简单介绍如何制作。

注:由于本文适用于对ACCESS数据库、HTML、ASP有一定了解的读者。

一、论坛结构分析

通过上面的功能需求分析,我们可以将论坛的制作分为四大部分:

(1) 网友注册和管理模块:因为引入了站长或者版主,在论坛中就必须能够对其进行身份验证。这个模块的功能,就是管理注册的网友,并能够提供相关的查询。比如,查询指定作者的所有发表的文章,查询当前发表文章最多的十个网友,等等。如果你的论坛不是很大,这个模块可以省略为只带有版主身份验证的功能,而去掉那些关于注册,查询的部分。

(2) 文章显示模块:显示所有版主审核过的,觉得值得推荐的文章。

(3) 发表文章模块:为注册网友提供发表见地的地方,发表后等待版主审阅。

(4) 文章审阅模块:版主对所有网又发表但未经审阅的文章进行处理,已决定是发表还是删除。

了解了具体的功能需求后,就可以按模块的开始论坛的设计了。当然,这些模块的只是在功能上对论坛结构的划分,实际上并不能够完全的把他们独立出来进行设计。对于这种较小的应用,也没有必要进行完全的模块化设计,在良好的规划下直接写程序代码或许来的更为简单一些。

对于论坛实现起来有一般两种方法:用文件或者数据库。相对而言,用数据库要简单高效一些,能够对论坛进行更好的控制,也能够对资料提供一些验证和保护。这儿我使用的是ACCESS数据库,对于一般的中小型的应用,ACCESS应该是能够胜任的。

从上面的分析可以知道应该有四个表,下面我给出每个表的结构。

(1)作者表(用来存放作者讯息):

ID:  文本类型,必填。是网友代号。

密码: 文本类型,必填。

昵称: 文本类型,必填。

EMAIL: 文本类型,必填。

职务: 数字类型,必填。-1代表普通网友,0代表站长。大于0的数字代表版主。

文章数:数字类型,必填。网友发表的文章总数。

姓名: 文本类型,可选。

性别: 文本类型,可选。

电话: 文本类型,可选。

(2)内容表(用来存放具体文章内容和相关讯息):

ID:自动编号,并为其设置索引,以加快搜寻的速度。

看板ID:数字类型,来自看板列表,表示文章所属看板。

主题ID:数字类型,来自主题表,表示文章所属主题。

作者ID:文本类型,来自作者表,表示文章的作者。

日期:日期/时间类型,预置初值为函数NOW(),自动取系统当前时间为其值。

标题:文本类型。文章的标题。

发表:是/否类型,为"真"时表示文章已经通过审阅,可以发表;为"否"表示文章尚待审阅。

推荐度:数字类型,文章的推荐程度。

内容:备注类型,文章的具体内容。

点击次数:数字类型,文章的点击次数。

(3)看板列表(用来存放有关看板的讯息):

ID:自动编号,同样的,也为其设置了索引。

名称:文本类型,看板的名称。

板主:文本类型,看板版主的ID。

主题数:数字类型,看板中包含的主题数。

(4)主题表(用来存放有关主题的讯息):

ID:自动编号,并为其设置索引。

标题:文本类型,表示主题名。

看板:数字类型,来自看板列表,表示主题所属的看板。

文章数:数字类型,主题中包含的文章数。

所有的表是设计完了,但是数据库的设计并没有完,所以我们还需要建立表间关系,这样就能够让数据库执行一些相关性检查,避免资料出错。建立表间关系的另外的一个好处,就是通过它能够很容易的建立出复杂的JOIN查询。

通常我们在ASP中操作数据库的时候,都是使用的执行时生成的查询,然后由传递给数据库解释执行。而在这儿我们要用的是存贮查询。与执行时查询比较而言,预存程序具有更多的优点。

它保存在数据库中,独立于ASP程序代码,使得他更容易建立和修改,并且查询的效率更高,速度更快,可以调试好了以后再放在ASP页面中使用,能避免很多问题。而且使用存贮查询的ASP程序代码更加容易阅读和修改。可能大家都对在ASP中使用SQL查询感到很烦,特别是那些逗号啊,分号啊什么的,一不小心就会出错。使用存贮查询后,就可以不用顾虑这些问题了。当然,预存程序再使用上也有一些要注意的地方,在后面我会详细的讲解它的使用方法。在ACCESS中建立预存程序是一件很容易的事,这儿我就不再多说了。在这儿我只给出各个查询的SQL语句程序代码。

我把所有要使用到的查询都作为预存程序保存在了数据库中,主要的有以下的一些:

(1)按ID查询文章:

(2)版主密码查询:

以下为引用的内容:
SELECT 看板列表.板主, 作者表.密码
FROM 作者表 INNER JOIN 看板列表 ON 作者表.ID = 看板列表.板主
WHERE (((看板列表.ID)=[id];

(3)查询作者:

以下为引用的内容:
SELECT 作者表.*
FROM 作者表
WHERE (((作者表.ID)=[id]));

(4)发表文章列表:

以下为引用的内容:
SELECT [内容表].[ID], [内容表].[标题], [内容表].[作者ID] AS 作者, [内容表].[日期], [内容表].[推荐度], [内容表].[点击次数] AS 点击数。
FROM 内容表
WHERE ((([内容表].[主题ID])=[TopicIndex]) And (([内容表].[发表])=True));

未发表文章列表:

以下为引用的内容:
SELECT 内容表.ID AS 文章id, 主题表.ID AS 主题id, 主题表.标题 AS 主题, 内容表.标题 AS 标题, 内容表.作者ID AS 作者, 内容表.日期 AS 日期
FROM 主题表 INNER JOIN 内容表 ON 主题表.ID = 内容表.主题ID
WHERE (((内容表.发表)=False) AND ((内容表.看板ID)=[boardid]));

(5)主题列表:

以下为引用的内容:
SELECT 主题表.*, 看板列表.名称 AS 看板名
FROM 看板列表 INNER JOIN 主题表 ON 看板列表.ID = 主题表.看板
WHERE (((主题表.看板)=[boardIndex]));

还有一些查询,因为大多类同,我就不一一列出了。

在上面的查询语句中,可以看到一些由"["和"]"包围起来的东西,那就是查询参数了。需要在执行时给出参数值,然后把参数值带入到查询语句中才能够执行。还有一点要注意的是:在建立那些INNER JOIN查询时,是需要把表间关系添加到设计视图中的,否则是不能够自动生成INNER JOIN查询语句的。

到这儿,数据库的设计就算完了,以后的工作就是ASP的事了。

二、构建

1、构建主窗体

先要给出一个窗体,能够让网友输入注册讯息,这些是HTML的内容,且放在一边,我们来仔细看看具体实现注册的ASP脚本。

(1)将资料中的单引号改成两个单引号,并且在前后加上单引号

以下为引用的内容:
Function SqlStr( data )
SqlStr = "'" & Replace( data,"'", "''" ) & "'"
End Function

注:这是一个自定义的函数,用来把用户输入中的单引号(')转换成两个单引号('')。在ASP中,用双引号围着的是字符串,因而上面的"'"代表的就是只有一个单引号的字符串。之所以要把一个单引号换成两个单引号,这是因为在SQL语句中,用单引号围起来是用来代表变量的。为了不至于混淆,就要把字符串中的单引号用两个单引号来表示。而所有的用户输入都要作为变量嵌入到SQL语句中的,所以这个函数是必不可少的。

(2)存贮准备

以下为引用的内容:
id=Request("id")
password=Request("password")
nickname=Request("nickname")
email=Request("email")
sex=request("sex")


注:把来自用户输入窗体中的内容保存在变量中,这不是必须的,但写了更容易读写。

以下为引用的内容:
if Request("name")=""then name=" " else name=request("name")
if Request("phone")=""then phone=" " else phone=request("phone")

因为这些内容不是必须填的,为了防止用户没有输入任何内容,而造成数据库操作上的错误,就必须把没有填入字段用空格来代替。

(3)建立连接

以下为引用的内容:
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")

注:这一段是建立数据库连接,数据库的名称为bbssystem.mdb,这一段中唯一要注意的是Server.MapPath函数的应用。一般来说,凡是涉及到具体的目录的地方,都不要直接使用目录名,而用Server.MapPath函数来代替。善用好Server.MapPath和Request.ServerVariables()等函数,能够让你的WEB应用具有更好的可移植性。

以下为引用的内容:
Set cmd = Server.CreateObject("ADODB.Command")

(4)查询作者是否已存在

以下为引用的内容:
Set cmd.ActiveConnection = conn
cmd.CommandText = "查询作者"
ReDim param(0) ' 声明参数数组
param(0) = CStr(id) ' Cint 不可忽略
Set rs = cmd.Execute( ,param )

注:这一段就是用来执行预存程序的。在ADO中执行查询的方法有很多种,但是对于预存程序就只能使用Command对象了。首先,建立了一个叫做cmd的Command对象,然后把conn连接对象设定给cmd对象的ActiveConnection属性,把要执行的查询名称"查询作者"设定给CommandText属性,然后为查询参数赋值。我们声明了一个参数数组param(0),因为在"查询作者"这个查询中只有一个参数,所以数组就只有一个分量了。一般的,在查询中有几个参数,就要申明有相应分量个数的参数数组。并且参数出现的顺序是个数组中分量的顺序是对应的。在使用参数查询的过程中,尤其要注意的是,参数的类型要严格匹配,否这就会出错,所以上面的CStr()类型转换函数是不可缺少的。

以下为引用的内容:
if not (rs.eof or rs.bof) then
response.write "错误,你输入的ID号已经被占用,请换一个再试试!"
else
sql = "Insert Into 作者表 (id, 昵称,Email, 密码,姓名,学校,系别,性别,电话) Values("
sql = sql & SqlStr(id) & ","
sql = sql & SqlStr(nickname) & ","
sql = sql & SqlStr(email) & ","
sql = sql & SqlStr(password) & ","
sql = sql & SqlStr(name) & ",&", "
sql = sql & SqlStr(sex) & ","
sql = sql & SqlStr(phone) & ")"
conn.Execute sql

使用一个SQL的Insert语句把资料插入到数据库中。其实这一查询也可以做成预存程序放在数据库中,我偷了点懒:-)不过对比之下也可以看到预存程序的好处,执行时查询写起来实在是太麻烦了。