(摘自CCU新聞組,本來出處可能是臺灣出版的一本關于php的書:PHP寶典) 
大部份的網站,都會考慮到和使用者之間的互動關系。這時,用留言版的功能,可讓使用者留下到此一游,或者是一些和網站的互動訊息。 
                                                                                            在設計上,可以很簡單的只留下使用者的短篇留言,也可以設計到依性質分門別類很復雜的 Web BBS 系統(tǒng)。當然,要如何打造一個屬于自己網站的留言版,就端賴網站的性質以及 Web 網站開發(fā)人員的巧思了。 
在這里介紹的范例,是簡單的列示所有留言的內容。供使用者可以一次看到多筆留言的資料。系統(tǒng)的后端存放留言是用 Oracle 7.x 版的資料庫系統(tǒng)。范例中的資料庫(database) 名稱為 WWW,連線的使用者帳號為 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 各欄位說明及具體資料見下表 
序號 欄位 名稱 資料形態(tài) 資料長度 欄位說明 限制 Key 
0 流水號 serial varchar2 255 NN PK 
1 參照流水號 ref varchar2 255 暫保留。供回 
覆留言功能用 
2 帳號 id char 8 使用者帳號 NN 
3 匿名 alias varchar2 32 顯示的名字 NN 
4 網址 ip varchar2 1024 上網 IP 
5 時間 msgdate date NN 
6 電子郵件 email varchar2 1024 
7 留言內容 msg varchar2 2000 NN 
8 顯示旗標 flag char 1 0: 不顯示 
1: 顯示 (內定) 
在本節(jié)的留言版相關程式中,若加入了使用者認證功能,則可以在 guestbook資料表的帳號欄中留下使用者的認證帳號,方便 Webmaster 日后找尋不當的發(fā)信者。在這兒先留下欄位,讓需要的讀者們實習了。 
要使用本節(jié)的程式,首先要先裝好 Oracle 7.x 版,并確定 Web Server 端的SQL*net 可以順利連上 Oracle 資料庫。之后還要在編譯 PHP 時加 
--with-oracle=/home/oracle/prodUCt/7.3.2 的選項,當然改成其它的路徑也沒關系,只要該路徑真的是 Oracle 的路徑即可。有關 Oracle 裝設及使用上的細節(jié)請參考相關書籍。 
下面的程式是將使用者的留言資訊加到 guestbook 留言資料表中。若要設定使用者認證功能,可在程式剛開始時檢查,發(fā)留言者就可以確認身份,而讀取留言就不必身份檢查。這種設定可以防止不當發(fā)言,卻又不會讓留言功能只有少數人使用。 
<?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>代號小名</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>內容</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í)行時,先檢查變數 alias 和 msg 是否有資料,若無資料則送出填寫留言的表格到使用者端,供使用者填寫留言。 
若使用者填好留言,按下 "送出留言" 的按鈕后,則執(zhí)行程式的前半部份。 
                         
程式大概分成五部份 
1.. 設定 Oracle 需要的環(huán)境變數 
2.. 連上 Oracle 資料庫 
3.. 整理資料,送入 Oracle 中 
4.. 結束與 Oracle 的連線 
5.. 結束程式,顯示最新的留言資料 
在設定 Oracle 環(huán)境的部份,用 PHP 的函式 putenv(),可設定作業(yè)系統(tǒng)層的環(huán)境變數。要使用中文要記得加入下面這行 
putenv("NLS_LANG=american_taiwan.zht16big5"); 
之后就使用 Oracle 函式庫的功能: ora_LOGOn() 等等。詳見 Oracle 資料庫函式庫。利用這個函式庫,可以很輕易的操作 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 變數為獨一無二的字串,程式先亂數產生獨特的字串,再用 md5 編碼,將字串弄亂,形成類似雜湊處理后的無意義字串。由于字串長,又變得很亂,可防止使用者,尤其是駭客或飛客利用序號來戳系統(tǒng)。 
$ref 變數目前是無效的。$id 變數為使用者認證用,若在程式開始處有加入使用者認證的程式,則 $PHP_AUTH_USER 會變成使用者的帳號,傳入 $id 變數中。 
至于使用者寫的字串,為了防止資料庫或處理時的復雜性甘脆將它用 BASE64 編碼。可以讓中文字的希奇字元一字消失,當然這是鋸箭法,不過對 Web 程式而言,執(zhí)行快速、修改方便才是最重要的,實在沒有必要再浪費精力去處理這些中文的沖碼問題了。值得注重的是使用 BASE64 編碼,會讓字串膨脹大約 1/3,若資料庫的儲存空間有限,可能就不適合用這個方法了,話又說回來,現在硬碟便宜,隨便就是十幾 GB 以 
上,應該不會考慮資料庫空間有限的問題才對。 
最后,將變數整理成 $query 字串,供資料庫執(zhí)行 SQL 指令使用就可以了。 
ora_parse($cursor, $query) or die; 
ora_exec($cursor); 
ora_close($cursor); 
ora_LOGOff($handle); 
要執(zhí)行 Oracle 的 SQL 指令前,要先經過 parse 的動作。若在前面加上 @ (如: @ora_prase();),可以不讓使用者看到錯誤訊息。在執(zhí)行 qu