前言:現在網路上的論壇到處都有,但不知您是否遇到過這樣的情況:在雜亂無章的討論訊息中來尋找自己想要的內容,是一件很費時費力的事情,到後來,您就都不想去看什麼論壇了。那我們能不能為自己網站論壇的內容增加審核功能呢?即所有網友發到論壇的文章,並不立即被顯示出來,必須經過站長或版主審閱之後,認為有價值,有必要推薦給其它網友的,就發表出來。否則就刪除了,免得浪費空間,搞得有點像精華區的意味,這樣你的論壇比起一般的論壇來,能夠提供給為明確有益的內容。放到你的網站上,應該可以吸引更多的網友來訪問。這個設想當然可以實現,以下我就簡單介紹如何製作。
註:由於本文適用於對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查詢文章:
SELECT 主題表.標題AS 主題名, 看板列表.姓名AS 看板名,內容表.*
FROM 主題表INNER JOIN (內容表INNER JOIN 看板清單ON 內容表.看板ID = 看板清單.ID) ON 主題表.ID = 內容表.主題ID
WHERE (((內容表.ID)=[articleid]));
(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語句把資料插入資料庫。其實這項查詢也可以做成預存程式放在資料庫中,我偷了點懶:-)不過對比之下也可以看到預存程式的好處,執行時查詢寫起來實在是太麻煩了。
2.建構文章顯示模組
前面說過,一片具體的文章是分屬在看板和主體之下的。因此顯示文章也要經過看板列表和主體列表這兩個頁面後,才能得到特定主題下文章的列表。
(1)板列表的顯示頁:
< html>
< head>
< title>看板列表< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
(2)開啟連接,顯示看板列表
< %Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
sql = "select * from 看板清單"
set rs=conn.execute(sql)
%>
註:簡單的SQL查詢,把所有的看板有關訊息傳回到紀錄集RS中。以下的任務就是顯示紀錄記得內容,並在對應的看板名稱上建立顯示看板主題的連結。
< body bgcolor="#FFFFFF">
< h2 align="center">看板列表</h2>
< table width="60%" border="0"cellspacing="0" cellpadding="0"align="center">
< tr bgcolor="#FFFFCC">
< td height="35" width="25%">看板名稱</td>
< td height="35" width="21%">板主</td>
< td height="35" width="23%">主題數</td>
< td height="35" width="31%">板主登陸</td>
< /tr>
註:這兒一部分是顯示出表格中每一列的標題,這兒我沒有用一個統一的函數來顯示RS紀錄記的內容,因為這樣可以對錶格的外觀和風格做更多的控制,使用起來雖然有點麻煩,但卻更靈活。
< %
do
boardid=rs("id")
boardname=rs("名稱")
boardmanager=rs("板主")
response.write "< tr>< td><a href=qBoard.asp?boardid="& boardid& "&boardname=" & boardname& ">" & boardname &"< /a>< /td>"
註:這一行是重點,當點擊了各個板的名稱後,可以連接到顯示看板主題的頁面。程式碼看起來有點麻煩,我分解了給你講,你就會明白了。點擊之後,瀏覽器請求使用的是qBoard.asp頁面,並帶有一個參數boardid,代表要顯示看板的ID號,在請求頁面和參數之間用問號(?)分隔。 Boardid是前面設定了的變量,其中包含的就是對應看板的ID號碼。這個連線中還帶有另一個參數boardname,用來把看板名稱傳遞給qBoard.asp頁面。在多個參數間使用"&"來分隔。這個參數不是必須的,傳遞過去是為了免得在qBorad.asp中再次用boardid來查詢看板名稱。一般來說,能夠少用資料庫操作就應盡量的少用,這樣可以提高ASP頁面的效能。因為Response.Write語句使用字串作為參數的,所以上面的字串和變數之間使用的是"&"聯結符。最後ASP頁面解釋的結果應該是像這樣的
<td>< a href=qBoard.asp?boardid=1&boardname=系統板>系統板< /a>< td>。
response.write "< td>< a href=qAuthor.asp?author="&boardmanager & ">" &boardmanager & "< /a></td>"
response.write "< td>" &rs("主旨數") & "< /td>"
response.write "< td>< a href=managerlogin.asp?boardid="&boardid & ">板務處理< /a></td>< /tr>"
註:在這個表格中,除了可以由連接來顯示看板主題的內容,還有一個斑竹查詢部分和板務處理部分,版主查詢可以是透過qAuthor.asp來實現的,它只是簡單的從資料庫中取出作者訊息,並顯示出來,這兒就不多說了。而板務處理是由managerlogin.asp頁面來處理的。這屬於文章審閱模組,我在後面再詳說。
rs.movenext
loop until rs.eof
%>
註:透過一個do … loop循環,把紀錄集中所有的訊息都顯示了出來。
< /table>
< div align="center"><br>
點擊看板名稱可以得到主題列表,點擊板主名稱可以察看板主訊息
< /div>
< /body>
< /html>
< %
set rs=nothing
conn.close
set conn=nothing
%>
(3)打造qBaord.asp頁面:
< %
boardid=request("boardid") '取出由上一頁傳遞過來的看板ID號
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "主題清單"
ReDim param(0) //註:宣告參數數組
param(0) = CLng(boardid)//註:CLng 不可忽略
Set rs = cmd.Execute( ,param )
%>
< html>
< head>
< title>主題列表< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
< h1 align="center"><%=rs("看板名")%>板主題列表</h1>
< table width="80%" border="0"cellspacing="0" cellpadding="0"align="center">
< tr bgcolor="#FFFFCC">
< td width="89%" height="21">主題</td>
< td width="11%" height="21">文章數</td>
< /tr>
< %
do
topicid=rs("id")
topicname=rs("標題")
sum=rs("文章數")
response.write "< tr>< td><a href=qtopic.asp?topicid=" & topicid& "&boardname=" & boardname& ">" & topicname &"< /a>< /td>"
response.write "< td>" &sum & "< /td>< /tr>"
rs.movenext
loop until rs.eof
%>
< /table>
< /body>
< /html>
註:qBoard.asp列出了某個版面下的所有的主題,在點擊了主題名稱後就會進入對應的主題文章清單。這個清單的是由qTopic.asp這個ASP腳本來實現的。 Qtopic.asp的程式碼在本質上幾乎和qBoard.asp沒有區別,只是在各自的細節上有所區別,這兒也不打算再多講了。
(4)點擊了文章清單中的文章標題後,會進入文章內容瀏覽頁article.asp:
< %
articleid=request("articleid")
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver(*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "按id查詢文章"
ReDim param(0) ' 聲明
param(0) = CLng(articleid) ' Cint 不可忽略
Set rs = cmd.Execute( ,param )
author=rs("作者id")
title=rs("標題")
data=rs("日期")
rate=rs("推薦度")
boardid=rs("看板id")
topicid=rs("主題id")
boardname=rs("看板名")
topicname=rs("主題名")
content=rs("內容")
content=replace(content,vbCrlf,"</p>< p>")
content="< p>" & content& "< /p>"
註:這是一個要注意的地方,在內容欄位中包含的是備忘類型的文本,其中可以包含換行字元。在HTML的顯示中,必須要把換行字元(也就是vbCrlf常數)換成HTML的段落符號。這樣在段落與段落的銜接處,就不會打亂原來輸入時的格式。如果要設計的更好些,可以透過CSS來重設義< P>標籤,設定其test-indent屬性,就可以實現每段開頭空格了。
(5)把點擊次數加一
sql="Update 內容表Set 點選次數=點選次數+1Where ID=" & articleid
conn.execute sql
註:這兒有一個SQL語句,沒當頁面被顯示的時候,會把對應的表中點擊次數欄位加一,這樣就能夠對文章瀏覽的次數做出統計,並可依序排名。在執行條語句的時候,我發現:本來在SQL語句中,嵌入的變數名稱應該加上單引號以與區別,但在這兒的articleid變數上我並沒有加單引號,居然也能夠通過,而我以前這樣寫從來都是會引發錯誤的,不知是不是由於新版本的ADO的緣故。
set cmd=nothing
%>
< html>
< head>
< title>Untitled Document< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#E9E9E4">
< table width="89%" border="0"cellspacing="0" cellpadding="0"align="center">
< tr bgcolor="#CCCCCC">
< td>作者:< font color="#FF3366"><a href="qauthor.asp?author=< %=author%>">< %=author%> < /a>< / 發佈日期: < font color="#FF3333"><%=data%>< /font>
看板:< font color="#FF3333"><a href="qboard.asp?boardid=< %=boardid%>">< %=boardname%>< /a>< /font>板主推薦:< font color="#FF3333">#rate#</font>< /td>
< /tr>
< tr bgcolor="#CCCCCC">
< td>標題:< font color="#FF3333"><%=title%>
主題:< a href="qtopic.asp?topicid=<%=topicid%>"> < %=topicname%>< /a> < /font>< /td>
< /tr>
< tr valign="top">
< td>
< hr>
< font color="#FF3366">文章內容:< /font>< br>
< br>
< font color=blue>< %response.writecontent%>< /font>
< br>
< br>
< /td>
< /tr>
< tr valign="top">
< td height="18">
< table width="50%" border="0"cellspacing="0" cellpadding="0"align="right" bgcolor="#CCCCCC">
< tr>
< td width="0%"> < /td>
<td width="65%">關於此主題<a href="submit.asp?topicid=< %=topicid%>&boardid=<%=boardid%>">發表評論< /a></td>
這個這個這個這個連結允許網友對此評論的話題發表自己的見解,這是下一個模組要講的內容了,這兒且按下不表。
< /tr>
< /table>
< /td>
< /tr>
< /table>
< /body>
< /html>
< %
set rs=nothing
conn.close
set conn=nothing
%>
到此,文章顯示部分也完成了。下面再來看看文章發表部分是如何實現的。
3.建構文章發表部分
文章發表模組只有兩個頁面,一個是前面提到的用來提供輸入窗體的submit.asp,還有一個是用來處理窗體輸入的subresult.asp。前面的那個頁面很簡單,基本上就是一個HTML窗體,沒有什麼好講的,下面來看看subresult.asp的內容:
< html>
< head>
< title>發表文章< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
< %
author=request("author")
password=request("password")
topicid=request("topicid")
boardid=request("boardid")
content=request("content")
title=request("title")
註:這段取出在submit.asp中提交的表格但內容,放在對應的變數中。
< html>
< head>
< title>發表文章< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
< %
author=request("author")
password=request("password")
topicid=request("topicid")
boardid=request("boardid")
content=request("content")
title=request("title")
(1)查詢作者是否已存在
cmd.CommandText = "select * from 作者表where id='" & author &"'"
Set rs = cmd.Execute()
(2)檢查權限
cmd.CommandText = "select * from 作者表where id='" & author &"'"
Set rs = cmd.Execute()
註:這一段是對作者權限進行檢查,對於帳號不存在或密碼錯誤做出對應的錯誤處理。在這裡可以看到response.end的用法,它是用來結束目前ASP腳本。結合if語句,可以對程式中的預期錯誤進行處理。在一個好的WEB應用中,錯誤處理是不可或缺的。
(3)將資料中的單引號改成兩個單引號,並且在前後加上單引號
Function SqlStr( data )
SqlStr = "'" & Replace( data,"'", "''" ) & "'"
End Function
'寫入資料庫
sql = "Insert Into 內容表(看板id,主題id,作者id,標題,內容)Values( "
sql = sql & SqlStr(topicid) & ","
sql = sql & SqlStr(boardid) & ","
sql = sql & SqlStr(author) & ","
sql = sql & SqlStr(title) & ","
sql = sql & SqlStr(content) & ")"
conn.Execute sql
%>
< h2>文章已經被送到資料庫,當板主審閱後就可以看到了<h2>
< /body>
< /html>
到這兒,文章已經被儲存在資料庫中了。但是,它並不能夠立刻被顯示出來,還需要版主的認可才行。下面,就來看看論壇的管理部分的內容。
4.論壇的管理部分
這兒是我們這個論壇的核心之所在,但它實現起來也沒有什麼特別的地方。還是那些老東西:窗體處理,資料庫查詢,在用ASP把他們有機的結合起來。當進入了文章審閱模式(前面提到的板務處理)之後,最為首要的內容,應該是對版主的身份進行驗證了。下面來看看版主登陸頁:
< %
boardid=request("boardid")
(註:boardid是由進入這個頁面的連接所傳遞過來的,是要進行板務處理的看板的ID。透過它才能知道處理的是那個板的板務。)
Set conn = erver.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "板主密碼查詢"
ReDim param(0)
param(0) = CLng(boardid) //註:CLng 不可忽略
Set rs = cmd.Execute( ,param )
boardmanager=rs("板主")
set cmd=nothing
%>
< html>
< head>
< title>Untitled Document< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
< p>只有板主< %=boardmanager%>才能夠進入這個地方</p>
< p>請輸入驗證密碼, 並且為了保持身份驗證,請開啟瀏覽器的Cookies。 </p>
< form method="post" action="managerloginrest.asp">
< input type="password" name="password">
< input type="hidden" name="boardid"value=< %=boardid%>>
< input type="submit" name="Submit"value="確定">
< /form>
註:這個頁面只是用來登陸用的,它得到斑竹輸入的密碼後,並不能進行驗證,而是將驗證的工作放到下一個頁面中進行。實際上,密碼輸入和驗證的工作是可以放在一個頁面中完成的,只不過程式碼的結構安排上有點麻煩。
< /body>
< /html>
< %
set rs=nothing
conn.close
set conn=nothing
%>
現在得到了版主ID和輸入的密碼,下面就是進行驗證的工作managerloginrest.asp了,它接受上面那個文件中窗體的內容,並進行相關處理:
< %
response.buffer=true
註:把緩衝區設定為允許使用。這一則一般來說,是應該加在每個ASP頁面的首部的,這樣才能提高ASP頁面的效能。在打開了緩衝區後,ASP還有一些對應的特殊用法,後面會提及。
boardid=request("boardid")
password=request("password")
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "板主密碼查詢"
ReDim param(0) ' 聲明
param(0) = CLng(boardid)//註:CLng不可忽略
Set rs = cmd.Execute( ,param )
boardmanager=rs("板主")
if password< > rs("密碼")then %>
< html>
< head>
< title>驗證< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
密碼錯誤< /body>
< /html>
< %
else
session("beenthere")=boarded
註:使用Session來保持對版主的身份驗證,這必須要求客戶端瀏覽器的cookie被開啟了。因為Session是透過cookie來實現的。在這兒,把看板ID賦給Session變數beenthere,表示版主主已經通過了驗證。在後面的每個版務處理的頁面中,都要檢查beenthere是否和對應的看版ID相符。
url="boardmanager.asp?boardid="& boardid
response.redirect url
補充:初學ASP的時候總是為response.redirect這個方法感到困惑,屢用不爽,現在我來告訴你一些技巧。在使用它之前,必須透過response.buffer=true來讓ASP頁面使用緩衝區。這時,在ASP被解釋成HTML程式碼之前,它是放在緩衝區中的,而不直接被傳送的客戶端瀏覽器。還有一個必須知道的是:在使用response.redirect之前,是不能有任何實際的HTML程式碼被傳送到客戶端瀏覽器的,否則就會出錯。當然也有變通的方法,如果在response.redirect之前已經有HTML程式碼被解釋出來,可以用response.clear方法來清除緩衝區,然後就可以使用它來進行重設向了。
end if
%>
註:以下就是在上面驗證通過後重設向的目標:boardmanager.asp。它將列出了所有別有被處理的文章。
< %
boardid=request("boardid")
if session("beenthere")< >boardidthen response.redirect "forums.asp"
註:這就是檢驗版主身分的地方,因為前面已經透過cookie在斑竹的瀏覽器中作了標記,現在我們就能夠透過seesion來辨認版主的身分了。如果標示不符,就會透過response.redirect回到最開始的登陸頁面。如果版主瀏覽器的cookie沒有打開,那麼seesion("beenthere")的值會為空,同樣也無法進入這個頁面。
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
sql="select 名稱from 看板清單whereid=" & boardid
set rs=conn.execute(sql)
boardname=rs("名稱")
cmd.commandtext="未發表文章清單"
ReDim param(0)
param(0) = CLng(boardid)//註:Clng 不可忽略
Set rs = cmd.Execute( ,param )
set cmd=nothing
%>
< html>
< head>
< title>版務處理< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#FFFFFF">
< h1 align="center"><%=boardname%>版務管理< /h1>
< hr>
< %
if rs.eof or rs.bof then response.write "<H2>現在沒有文章要處理< /h2>"
response.end
%>
註:如果沒有新文章被網友發布,這給予對應的提示,並用response.end來結束此頁的顯示。
< table width="90%" border="0"cellspacing="0" cellpadding="0"align="center" >
< tr bgcolor="#FFFFCC">
< td width="40%" height="20">主題</td>
< td width="40%" height="20">文章標題</td>
< td width="8%" height="20">作者</td>
< td width="12%" height="20">日期</td>
< /tr>
< %
do
topicid=rs("主題id")
articleid=rs("文章id")
data=rs("日期")
datastr=cstr(year(data)) & "-"& cstr(month(data)) &"-"& cstr(day(data))
author=rs("作者")
articlename=rs("標題")
topicname=rs("主題")
response.write "< tr>< td><a href=qtopic.asp?topicid="& topicid& ">" & topicname &"< /A>< /td>"
response.write "< td>< a href=managearticle.asp?articleid="&articleid & "&boardid="& boardid &">" &articlename & "< /A>< /td>"
response.write "< td>< a href=qauthor.asp?author="&author & ">" & author& "< /a>< /td>"
response.write "< td>" &datastr & "< /td>< /tr>"
rs.movenext
loop until rs.eof
%>
< /table>
< /html>
< %
set rs=nothing
conn.close
set conn=nothing
%>
< /body>
當點擊了對應文章的聯結後,就進入此文章的處理頁面managearticle.asp:
< %
articleid=request("articleid")
boardid=request("boardid")
if session("beenthere")< >boardidthen response.redirect "forums.asp"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "按id查詢文章"
ReDim param(0)
param(0) = CLng(articleid)//註:Clng 不可忽略
Set rs = cmd.Execute( ,param )
author=rs("作者id")
title=rs("標題")
data=rs("日期")
rate=rs("推薦度")
boardid=rs("看板id")
topicid=rs("主題id")
boardname=rs("看板名")
topicname=rs("主題名")
content=rs("內容")
content=replace(content,vbCrlf,"</p>< p>")
content="< p>" & content& "< /p>"
set cmd=nothing
%>
< html>
< head>
< title>Untitled Document< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#E9E9E4">
< table width="89%" border="0"cellspacing="0" cellpadding="0"align="center">
< tr bgcolor="#CCCCCC">
< td>作者:< font color="#FF3366"><a href="qauthor.asp?author=< %=author%>">< %=author%> < /a>< / 發佈日期: < font color="#FF3333"><%=data%>< /font>
看板:< font color="#FF3333"><a href="qboard.asp?boardid=< %=boardid%>">< %=boardname%>< /a>< /font>板主推薦:< font color="#FF3333">#rate#</font>< /td>
< /tr>
< tr bgcolor="#CCCCCC">
< td>標題:< font color="#FF3333"><%=title%>
主題:< a href="qtopic.asp?topicid=<%=topicid%>"> < %=topicname%>< /a> < /font>< /td>
< /tr>
< tr valign="top">
< td>
< hr>
< font color="#FF3366">文章內容:< /font>< br>
< br>
< font color=blue>< %response.writecontent%>< /font>
< br>
< hr>
< /td>
< /tr>
< tr valign="top">
< form method="post" action="manageresult.asp">
< td height="18">
< table width="100%" border="1"cellspacing="1" cellpadding="1">
< tr>
< td width="29%">
< div align="right">
< input type="hidden" name="boardid"value="< %=boardid%>">
< input type="hidden" name="topicid"value="< %=topicid%>">
< input type="hidden" name="articleid"value="< %=articleid%>">
文章處理:< /div>
< /td>
< td width="12%" bordercolor="#006666">刪除:
< input type="radio" name="manage"value=1>
< /td>
< td width="30%" bordercolor="#006666">發表:
< input type="radio" name="manage"value=2>
推薦等級< select name="select">
< option value="1">1</option>
< option value="2">2</option>
< option value="3" selected>3</option>
< option value="4">4</option>
< option value="5">5</option>
< /select>
< /td>
< td width="20%" bordercolor="#006666">以後再處理:
< input type="radio" name="manage"value=3>
< /td>
< td width="9%">
< input type="submit" name="Submit"value="確定">
< /td>
< /tr>
< /table>
< /td>
< /form>
< /tr>
< /table>
< /body>
< /html>
< %
set rs=nothing
conn.close
set conn=nothing
%>
註:這一頁和文章顯示模組中的article.asp基本上是一樣的,只是多加入了版主處理的窗體,在這兒就不多講了。
下面,要根據版主的處理過程,修該資料庫對應部分
< %response.buffer=true%>
< html>
< head>
< title>文章處理< /title>
< meta http-equiv="Content-Type"content="text/html; charset=GB2312">
< /head>
< body bgcolor="#E9E9E4">
< %
articleid=request("articleid")
boardid=request("boardid")
topicid=request("topicid")
manage=request("manage")
'接受窗體內容
response.write manage '顯示斑竹ID
if session("beenthere")< >boardidthen response.redirect "forums.asp"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={Microsoft AccessDriver (*.mdb)};dbq=" & Server.MapPath("bbssystem.mdb")
根據上頁中版主的操作,以下進行對應的處理。
if CLng(request("manage"))=1 then
sql="delete from 內容表where id="& articleid
conn.execute sql
response.write "< h1>文章已經刪除</h1>"
response.write "< a href=>back</a>"
elseif CLng(request("manage"))=2then
sql="update 內容表set 發表=true whereid=" & articleid
conn.execute sql
sql="update 主題表set 文章數=文章數+1where id=" & topicid
conn.execute sql
response.write "< h1>文章已經發表</h1>"
response.write "< a href=>back</a>"
else
response.clear
response.redirect "boardmanager.asp?boardid="& boarded
end if
%>
< /body>
< /html>
< %
conn.close
set conn=nothing
%>
經過上面幾步,所有的部分就算是基本完成了,當然,這時還不能拿來用,擺不上檯面的。如果想要能夠拿得出來的話,還要在版面設計,客戶端資料驗證等方面多下一些功夫。不過那都是HTML的內容了,跟ASP沒多大的關係,這兒我就不多講了。