大部份的網(wǎng)站,都會(huì)考慮到和使用者之間的互動(dòng)關(guān)系。這時(shí),用留言版的功能,可讓使用者留下到此一游,或者是一些和網(wǎng)站的互動(dòng)訊息。?
在設(shè)計(jì)上,可以很簡單的只留下使用者的短篇留言,也可以設(shè)計(jì)到依性質(zhì)分門別類很復(fù)雜的?Web?BBS?系統(tǒng)。當(dāng)然,要如何打造一個(gè)屬于自己網(wǎng)站的留言版,就端賴網(wǎng)站的性質(zhì)以及?Web?網(wǎng)站開發(fā)人員的巧思了。?
在這里介紹的范例,是簡單的列示所有留言的內(nèi)容。供使用者可以一次看到多筆留言的資料。系統(tǒng)的后端存放留言是用?Oracle?7.x?版的資料庫系統(tǒng)。范例中的資料庫(database)?名稱為?WWW,連線的使用者帳號(hào)為?user38、密碼為?iam3849。要直接使用本例,必須先執(zhí)行下面的?SQL?指令,建立?guestbook?的資料表格。?
CREATE?TABLE?guestbook?(?
serial?varchar2(255)?not?null,?
ref?varchar2(255)?null,?
id?char(8)?not?null,?
alias?varchar2(32)?not?null,?
ip?varchar2(1024)?null,?
msgdate?date?not?null,?
email?varchar2(1024)?null,?
msg?varchar2(2000)?not?null,?
flag?char(1)?default?1,?
primary?key(serial)?
);?
上面的?SQL?各欄位說明及詳細(xì)資料見下表?
序號(hào)?欄位?名稱?資料形態(tài)?資料長度?欄位說明?限制?Key?
0?流水號(hào)?serial?varchar2?255?NN?PK?
1?參照流水號(hào)?ref?varchar2?255?暫保留。供回?
覆留言功能用?
2?帳號(hào)?id?char?8?使用者帳號(hào)?NN?
3?匿名?alias?varchar2?32?顯示的名字?NN?
4?網(wǎng)址?ip?varchar2?1024?上網(wǎng)?IP?
5?時(shí)間?msgdate?date?NN?
6?電子郵件?email?varchar2?1024?
7?留言內(nèi)容?msg?varchar2?2000?NN?
8?顯示旗標(biāo)?flag?char?1?0:?不顯示?
1:?顯示?(內(nèi)定)?
在本節(jié)的留言版相關(guān)程式中,若加入了使用者認(rèn)證功能,則可以在?guestbook資料表的帳號(hào)欄中留下使用者的認(rèn)證帳號(hào),方便?Webmaster?日后找尋不當(dāng)?shù)陌l(fā)信者。在這兒先留下欄位,讓需要的讀者們實(shí)習(xí)了。?
要使用本節(jié)的程式,首先要先裝好?Oracle?7.x?版,并確定?Web?Server?端的SQL*net?可以順利連上?Oracle?資料庫。之后還要在編譯?PHP?時(shí)加?
--with-oracle=/home/oracle/product/7.3.2?的選項(xiàng),當(dāng)然改成其它的路徑也沒關(guān)系,只要該路徑真的是?Oracle?的路徑即可。有關(guān)?Oracle?裝設(shè)及使用上的細(xì)節(jié)請(qǐng)參考相關(guān)書籍。?
下面的程式是將使用者的留言資訊加到?guestbook?留言資料表中。若要設(shè)定使用者認(rèn)證功能,可在程式剛開始時(shí)檢查,發(fā)留言者就可以確認(rèn)身份,而讀取留言就不必身份檢查。這種設(shè)定可以防止不當(dāng)發(fā)言,卻又不會(huì)讓留言功能只有少數(shù)人使用。?
<?php?
file://---------------------------?
//?新增留言程式?addmsg.php?
//?Author:?Wilson?Peng?
//?Copyright?(C)?2000?
file://---------------------------?
//?
//?可自行在這兒加入身份檢查功能?
//?
if?(($alias!="")?and?($msg!=""))?{?
putenv("ORACLE_SID=WWW");?
putenv("NLS_LANG=american_taiwan.zht16big5");?
putenv("ORACLE_HOME=/home/oracle/product/7.3.2");?
putenv("LD_LIBRARY_PATH=/home/oracle/product/7.3.2/lib");?
putenv("ORA_NLS=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
putenv("ORA_NLS32=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
$handle=ora_logon("user38@WWW","iam3849")?or?die;?
$cursor=ora_open($handle);?
ora_commitoff($handle);?
$serial=md5(uniqid(rand()));?
$ref="";?
$id=$PHP_AUTH_USER;?
$ip=$REMOTE_ADDR;?
$msg=base64_encode($msg);?
$flag="1";?
$query="INSERT?into?guestbook(serial,?ref,?id,?alias,?ip,?
msgdate,?email,?msg,?flag)?values('$serial',?'$ref',?'$id',?'$alias',?'$ip',?
sysdate,?'$email',?'$msg',?'$flag')";?
ora_parse($cursor,?$query)?or?die;?
ora_exec($cursor);?
ora_close($cursor);?
ora_logoff($handle);?
Header("Location:?./index.php");?
exit;?
}?else?{?
?>?
<html>?
<head>?
<title>填寫留言</title>?
</head>?
<body?bgcolor=ffffff>?
<form?method=POST?action="<??echo?$PHP_SELF;??>">?
<table?border=0?cellpadding=2?width=395>?
<tr>?
<td?nowrap><font?color=004080>代號(hào)小名</font></td>?
<td?width=20%><input?type=text?name=alias?size=8></td>?
<td?nowrap><font?color=004080>電子郵件</font></td>?
<td?width=50%><input?type=text?name=email?size=18></td>?
</tr>?
<tr>?
<td?nowrapvalign=top><font?color=004080>內(nèi)容</font></td>?
<td?width=80%?colspan=3><textarea?rows=5?name=msg?
cols=33></textarea></td>?
</tr>?
<tr>?
<td?width=100%?colspan=4?align=center>?
<input?type=submit?value="送出留言">?
<input?type=reset?value="擦掉留言">?
</td>?
</tr>?
</table>?
</form>?
</body>?
</html>?
<?php?
}?
?>?
上面的程式在執(zhí)行時(shí),先檢查變數(shù)?alias?和?msg?是否有資料,若無資料則送出填寫留言的表格到使用者端,供使用者填寫留言。?
若使用者填好留言,按下?"送出留言"?的按鈕后,則執(zhí)行程式的前半部份。?
程式大概分成五部份?
1..?設(shè)定?Oracle?需要的環(huán)境變數(shù)?
2..?連上?Oracle?資料庫?
3..?整理資料,送入?Oracle?中?
4..?結(jié)束與?Oracle?的連線?
5..?結(jié)束程式,顯示最新的留言資料?
在設(shè)定?Oracle?環(huán)境的部份,用?PHP?的函式?putenv(),可設(shè)定作業(yè)系統(tǒng)層的環(huán)境變數(shù)。要使用中文要記得加入下面這行?
putenv("NLS_LANG=american_taiwan.zht16big5");?
之后就使用?Oracle?函式庫的功能:?ora_logon()?等等。詳見?Oracle?資料庫函式庫。利用這個(gè)函式庫,可以很輕易的操作?Oracle?資料庫。?
再來就是整理資料,以便置入?Oracle?資料庫中?
$serial=md5(uniqid(rand()));?
$ref="";?
$id=$PHP_AUTH_USER;?
$ip=$REMOTE_ADDR;?
$msg=base64_encode($msg);?
$flag="1";?
$query="INSERT?into?guestbook(serial,?ref,?id,?alias,?ip,?msgdate,?
email,?msg,?flag)?values('$serial',?'$ref',?'$id',?'$alias',?'$ip',?sysdate,?
'$email',?'$msg',?'$flag')";?
$serial?變數(shù)為獨(dú)一無二的字串,程式先亂數(shù)產(chǎn)生獨(dú)特的字串,再用?md5?編碼,將字串弄亂,形成類似雜湊處理后的無意義字串。由于字串長,又變得很亂,可防止使用者,尤其是駭客或飛客利用序號(hào)來戳系統(tǒng)。?
$ref?變數(shù)目前是無效的。$id?變數(shù)為使用者認(rèn)證用,若在程式開始處有加入使用者認(rèn)證的程式,則?$PHP_AUTH_USER?會(huì)變成使用者的帳號(hào),傳入?$id?變數(shù)中。?
至于使用者寫的字串,為了防止資料庫或處理時(shí)的復(fù)雜性甘脆將它用?BASE64?編碼。可以讓中文字的奇怪字元一字消失,當(dāng)然這是鋸箭法,不過對(duì)?Web?程式而言,執(zhí)行快速、修改方便才是最重要的,實(shí)在沒有必要再浪費(fèi)精力去處理這些中文的沖碼問題了。值得注意的是使用?BASE64?編碼,會(huì)讓字串膨脹大約?1/3,若資料庫的儲(chǔ)存空間有限,可能就不適合用這個(gè)方法了,話又說回來,現(xiàn)在硬碟便宜,隨便就是十幾?GB?以?
上,應(yīng)該不會(huì)考慮資料庫空間有限的問題才對(duì)。?
最后,將變數(shù)整理成?$query?字串,供資料庫執(zhí)行?SQL?指令使用就可以了。?
ora_parse($cursor,?$query)?or?die;?
ora_exec($cursor);?
ora_close($cursor);?
ora_logoff($handle);?
要執(zhí)行?Oracle?的?SQL?指令前,要先經(jīng)過?parse?的動(dòng)作。若在前面加上?@?(如:?@ora_prase();),可以不讓使用者看到錯(cuò)誤訊息。在執(zhí)行?query?指令后,就可以關(guān)閉與?Oracle?之間的連線了。?
Header("Location:?./index.php");?
exit;?
這二行讓瀏覽器重導(dǎo)到?index.php。讓使用者看到他的新留言,就完成了留言的動(dòng)作。?
之后來看看留言的內(nèi)容顯示程式。?
<html>?
<head>?
<meta?content="text/html;?charset=gb2312"?
http-equiv=Content-Type>?
<title>留言版</title>?
</head>?
<body?bgcolor=ffffff>?
<?php?
file://---------------------------?
//?留言顯示程式?index.php?
//?Author:?Wilson?Peng?
//?Copyright?(C)?2000?
file://---------------------------?
$WebmasterIPArray?=?
ay(?
"10.0.1.30",?//?管理人員甲的機(jī)器?IP?
"10.0.2.28"?//?管理人員乙的機(jī)器?IP?
);?
$WebmasterIP=false;?
for?($i=0;?$i<Count($WebmasterIPArray);?$i++)?{?
if?($REMOTE_ADDR?==?$WebmasterIPArray[$i])?$WebmasterIP=true;?
}?
putenv("ORACLE_SID=WWW");?
putenv("NLS_LANG=american_taiwan.zht16big5");?
putenv("ORACLE_HOME=/home/oracle/product/7.3.2");?
putenv("LD_LIBRARY_PATH=/home/oracle/product/7.3.2/lib");?
putenv("ORA_NLS=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
putenv("ORA_NLS32=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
$handle=ora_logon("user38@WWW","iam3849")?or?die;?
$cursor=ora_open($handle);?
ora_commitoff($handle);?
$query="SELECT?serial,?ref,?id,?alias,?ip,?TO_CHAR(msgdate,?'yyyy/mm/dd?hh:mi:ss'),?email,?msg?FROM?guestbook?where?flag='1'?order?by?msgdate?desc";?
ora_parse($cursor,?$query)?or?die;?
ora_exec($cursor);?
$i=0;?
while(ora_fetch($cursor))?{?
$guestbook[$i][0]?=?ora_getcolumn($cursor,0);?
$guestbook[$i][1]?=?ora_getcolumn($cursor,1);?
$guestbook[$i][2]?=?ora_getcolumn($cursor,2);?
$guestbook[$i][3]?=?ora_getcolumn($cursor,3);?
$gu?
estbook[$i][4]?=?ora_getcolumn($cursor,4);?
$guestbook[$i][5]?=?ora_getcolumn($cursor,5);?
$guestbook[$i][6]?=?ora_getcolumn($cursor,6);?
$guestbook[$i][7]?=?ora_getcolumn($cursor,7);?
$i++;?
}?
ora_close($cursor);?
ora_logoff($handle);?
echo?"<a?href=addmsg.php>新增留言....</a><p>\n";?
if?($QUERY_STRING!="")?
$page?=?$QUERY_STRING;?
}?else?
$page?=?0;?
}?
$i=count($guestbook);?
$msgnum=20;?//?每頁二十筆?
$start?=?$page?*?$msgnum;?
$end?=?$start?+?$msgnum;?
if?($end?>?$i)?$end=$i;?
$totalpage=$i/$msgnum;?
$pagestr="";?
if?($page>0)?$pagestr=$pagestr."<a?
href=index.php?".($page-1)."><上頁</a>?-?";?
$pagestr=$pagestr."[第?";?
for?($i=0;?$i<$totalpage;?$i++)?
if?($i!=$page)?
$pagestr?=?$pagestr."<a?href=index.php?$i>".($i+1)."</a>?";?
}?else?
$pagestr?=?$pagestr.($i+1)."?";?
}?
}?
$pagestr=$pagestr."?頁]?";?
if?($page<($totalpage-1))?$pagestr=$pagestr."-?<a?
href=index.php?".($page+1).">下頁></a>?";?
$pagestr="<div?align=center>$pagestr</div>";?
echo?"<p>".$pagestr."<hr><p>\n";?
for?($i=$start;?$i<$end;?$i++)?
echo?"<p><hr><p>\n";?
echo?"<p>\n<font?color=e06060>".$guestbook[$i][5]."</font>?
?";?
if?($guestbook[$i][6]!="")?echo?"<a?
href=mailto:".$guestbook[$i][6].">";?
echo?"<strong>".$guestbook[$i][3]."</strong>";?
if?($guestbook[$i][6]!="")?echo?"</a>";?
echo?"<br>\n";?
if?($WebmasterIP)?echo?"<a?
href=erase.php?".$guestbook[$i][0].">刪除本篇!!</a>?(".$guestbook[$i][2].")?
?";?
echo?"<font?size=-1?color=c0c0c0>from:?
".$guestbook[$i][4]."</font><p>\n";?
$msg=base64_decode($guestbook[$i][7]);?
$msg=nl2br($msg);?
echo?$msg;?
echo?"<p>\n";?
}?
echo?"<p><hr><p>\n";?
echo?$pagestr;?
?>?
</body>?
</html>?
在顯示留言的部份,考慮到留言內(nèi)容若很多,加上網(wǎng)路慢的話,可能會(huì)讓使用者在線路慢的時(shí)候拖累整個(gè)資料庫,因此,盡快的連上資料庫,取得需要的資料后,馬上關(guān)閉資料庫,再慢慢送給使用者,應(yīng)是最好的對(duì)策。?
程式分成四部份?
1..?初始化?
2..?取資料庫中的資料?
3..?計(jì)算要顯示的頁數(shù)?
4..?送出資料?
這個(gè)程式在?BIGLOBE?上有實(shí)作,由于這是一間?ISP?公司,因此在設(shè)定時(shí)限定撥?
接或?qū)>€的會(huì)員才能看到,進(jìn)入前要輸入帳號(hào)及密碼。有興趣者不妨買個(gè)?BIGLOBE?的?
撥接帳號(hào)參考。為了保護(hù)留言者的隱私,留言以馬賽克處理。?
$WebmasterIPArray?=?array(?
"10.0.1.30",?//?管理人員甲的機(jī)器?IP?
"10.0.2.28"?//?管理人員乙的機(jī)器?IP?
);?
$WebmasterIP=false;?
for?($i=0;?$i<Count($WebmasterIPArray);?$i++)?{?
if?($REMOTE_ADDR?==?$WebmasterIPArray[$i])?$WebmasterIP=true;?
}?
//?之后初始化?Oracle?程式略?
顯示程式和留言程式的初始化部份都差不多,但顯示程式多加了一個(gè)功能,設(shè)定Webmaster?的電腦。將?Webmaster?使用的?IP?Address?加在?$WebmasterIPArray?陣列變數(shù)中,可以在顯示留言時(shí),顯示刪除留言的字串,方便處理不當(dāng)?shù)牧粞浴?
$handle=ora_logon("user38@WWW","iam3849")?or?die;?
$cursor=ora_open($handle);?
ora_commitoff($handle);?
$query="SELECT?serial,?ref,?id,?alias,?ip,?TO_CHAR(msgdate,?
'yyyy/mm/dd?hh:mi:ss'),?email,?msg?FROM?guestbook?where?flag='1'?order?by?
msgdate?desc";?
ora_parse($cursor,?$query)?or?die;?
ora_exec($cursor);?
$i=0;?
while(ora_fetch($cursor))?{?
$guestbook[$i][0]?=?ora_getcolumn($cursor,0);?
$guestbook[$i][1]?=?ora_getcolumn($cursor,1);?
$guestbook[$i][2]?=?ora_getcolumn($cursor,2);?
$guestbook[$i][3]?=?ora_getcolumn($cursor,3);?
$guestbook[$i][4]?=?ora_getcolumn($cursor,4);?
$guestbook[$i][5]?=?ora_getcolumn($cursor,5);?
$guestbook[$i][6]?=?ora_getcolumn($cursor,6);?
$guestbook[$i][7]?=?ora_getcolumn($cursor,7);?
$i++;?
}?
ora_close($cursor);?
ora_logoff($handle);?
在初始化后,就可以連上?Oracle?資料庫,將留言的資料取出放在?$guestbook陣列中。取得資料后,就趕緊將資料庫關(guān)閉,再來處理?$guestbook?陣列的資料了。?
if?($QUERY_STRING!="")?{?
$page?=?$QUERY_STRING;?
}?else?{?
$page?=?0;?
}?
這一段程式判斷是要顯示第幾頁,內(nèi)定值是顯示第一頁。要顯示第三頁的頁面,需要使用?http://xxxxxx/index.php?2?的格式,也就是傳入?$QUERY_STRING,余類推。之后的數(shù)行程式,都是用來處理顯示的頁數(shù)及筆數(shù)的資料。?
$msgnum=20;?//?每頁二十筆?
要改變每頁的顯示筆數(shù),可以改?$msgnum?變數(shù)。程式的內(nèi)定值為?20?筆。?
for?($i=$start;?$i<$end;?$i++)?{?
echo?"<p><hr><p>\n";?
echo?"<p>\n<font?color=e06060>".$guestbook[$i][5]."</font>? ?";?
if?($guestbook[$i][6]!="")?echo?"<a?
href=mailto:".$guestbook[$i][6].">";?
echo?"<strong>".$guestbook[$i][3]."</strong>";?
if?($guestbook[$i][6]!="")?echo?"</a>";?
echo?"<br>\n";?
if?($WebmasterIP)?echo?"<a?href=erase.php?".$guestbook[$i][0].">刪除?
本篇!!</a>?(".$guestbook[$i][2].")? ?";?
echo?"<font?size=-1?color=c0c0c0>from:?
".$guestbook[$i][4]."</font><p>\n";?
$msg=base64_decode($guestbook[$i][7]);?
$msg=nl2br($msg);?
echo?$msg;?
echo?"<p>\n";?
}?
這一段程式就是真正顯示留言資料給使用者看的程式了。利用?for?回圈,將$guestbook?陣列的資料按照設(shè)定的頁數(shù)取出,顯示給使用者看。值得一提的是,若看留言的機(jī)器?IP?為?$WebmasterIPArray?變數(shù)陣列中的一個(gè)元素的話,則會(huì)在留言者的匿稱后顯示?"刪除本篇!!"?的字串,供管理人員刪除不當(dāng)留言。?
以下即為刪除留言的程式。?
<?php?
file://---------------------------?
//?留言刪除程式?erase.php?
//?Author:?Wilson?Peng?
//?Copyright?(C)?2000?
file://---------------------------?
putenv("ORACLE_SID=WWW");?
putenv("NLS_LANG=american_taiwan.zht16big5");?
putenv("ORACLE_HOME=/home/oracle/product/7.3.2");?
putenv("LD_LIBRARY_PATH=/home/oracle/product/7.3.2/lib");?
putenv("ORA_NLS=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
putenv("ORA_NLS32=/home/oracle/product/7.3.2/ocommon/nls/admin/data");?
$handle=ora_logon("user38@WWW","iam3849")?or?die;?
$cursor=ora_open($handle);?
ora_commitoff($handle);?
$query="UPDATE?guestbook?set?flag='0'?where?
serial='".$QUERY_STRING."'";?
ora_parse($cursor,?$query)?or?die;?
ora_exec($cursor);?
ora_close($cursor);?
ora_logoff($handle);?
Header("Location:?./index.php");?
?>?
其實(shí)這個(gè)程式很單純,只要打開?Oracle?資料庫,將欲刪除的序號(hào)那筆資料的flag?欄位設(shè)成?0?就可以了,不用將資料真的從資料庫上移除。 |