PHP基礎教程:留言闆

發布時間:2007年03月13日      浏覽次數:2621 次
大(dà)部份的網站,都會考慮到和用戶之間的互動關系。這時,用留言闆的功能,可讓用戶留下(xià)到此一(yī)遊,或者是一(yī)些和網站的互動信息。
在設計上,可以很簡單的隻留下(xià)用戶的短篇留言,也可以設計到依性質分(fēn)門别類很複雜(zá)的 Web BBS 系統。當然,要如何打造一(yī)個屬于自己網站的留言闆,就端賴網站的性質以及 Web 網站開(kāi)發人員(yuán)的巧思了。
在這裏介紹的範例,是簡單的列示所有留言的内容。供用戶可以一(yī)次看到多筆留言的資(zī)料。系統的後端存放(fàng)留言是用 Oracle 7.x 版的數據庫系統。範例中(zhōng)的數據庫 (database) 名稱爲 WWW,連接的用戶帳号爲 user38、密碼爲 iam3849。要直接使用本例,必須先執行下(xià)面的 SQL 指令,建立 guestbook 的資(zī)料表格。
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 各字段說明及詳細資(zī)料見下(xià)表
序号 字段 名稱 資(zī)料類型 資(zī)料長度 字段說明 限制 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 顯示标志(zhì) flag char 1 0: 不顯示
1: 顯示 (默認)
在本節的留言闆相關程序中(zhōng),若加入了 用戶認證 功能,則可以在 guestbook 資(zī)料表的帳号欄中(zhōng)留下(xià)用戶的認證帳号,方便 Webmaster 日後找尋不當的發信者。在這兒先留下(xià)字段,讓需要的讀者們實習了。
要使用本節的程序,首先要先裝好 Oracle 7.x 版,并确定 Web Server 端的 SQL*net 可以順利連上 Oracle 數據庫。之後還要在編譯 PHP 時加入 --with-oracle=/home/oracle/product/7.3.2 的選項,當然改成其它的路徑也沒關系,隻要該路徑真的是 Oracle 的路徑即可。有關 Oracle 裝設及使用上的細節請參考相關書(shū)籍。
下(xià)面的程序是将用戶的留言信息加到 guestbook 留言資(zī)料表中(zhōng)。若要配置用戶認證功能,可在程序剛開(kāi)始時檢查,發留言者就可以确認身份,而讀取留言就不必身份檢查。這種配置可以防止不當發言,卻又(yòu)不會讓留言功能隻有少數人使用。
<?php
//---------------------------
// 新增留言程序 addmsg.php
// Author: Wilson Peng
// Copyright (C) 2000
//---------------------------
//
// 可自行在這兒加入身份檢查功能
//
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>代号小(xiǎ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>内容</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
}
?>
上面的程序在執行時,先檢查變量 alias 和 msg 是否有資(zī)料,若無資(zī)料則送出填寫留言的表格到用戶端,供用戶填寫留言。
若用戶填好留言,按下(xià) "送出留言" 的按鈕後,則執行程序的前半部份。
程序大(dà)概分(fēn)成五部份
配置 Oracle 需要的環境變量
連上 Oracle 數據庫
整理資(zī)料,送入 Oracle 中(zhōng)
結束與 Oracle 的連接
結束程序,顯示最新的留言資(zī)料
在配置 Oracle 環境的部份,用 PHP 的函數 putenv() ,可配置操作系統層的環境變量。要使用中(zhōng)文要記得加入下(xià)面這行
putenv ( "NLS_LANG=american_taiwan.zht16big5" );
之後就使用 Oracle 函數庫的功能: ora_logon() 等等。詳見 Oracle 數據庫函數庫 。利用這個函數庫,可以很輕易的操作 Oracle 數據庫。
再來就是整理資(zī)料,以便置入 Oracle 數據庫中(zhōng)
$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 變量爲獨一(yī)無二的字符串,程序先随機數産生(shēng)獨特的字符串,再用 md5 編碼,将字符串弄亂,形成類似哈稀處理後的無意義字符串。由于字符串長,又(yòu)變得很亂,可防止用戶,尤其是黑客或飛客利用序号來戳系統。
$ref 變量目前是無效的。$id 變量爲用戶認證用,若在程序開(kāi)始處有加入用戶認證的程序,則 $PHP_AUTH_USER 會變成用戶的帳号,傳入 $id 變量中(zhōng)。
至于用戶寫的字符串,爲了防止數據庫或處理時的複雜(zá)性甘脆将它用 BASE64 編碼。可以讓中(zhōng)文字的奇怪字符一(yī)字消失,當然這是鋸箭法,不過對 Web 程序而言,執行快速、修改方便才是最重要的,實在沒有必要再浪費(fèi)精力去(qù)處理這些中(zhōng)文的沖碼問題了。值得注意的是使用 BASE64 編碼,會讓字符串膨脹大(dà)約 1/3,若數據庫的儲存空間有限,可能就不适合用這個方法了,話(huà)又(yòu)說回來,現在硬碟便宜,随便就是十幾 GB 以上,應該不會考慮數據庫空間有限的問題才對。
最後,将變量整理成 $query 字符串,供數據庫執行 SQL 指令使用就可以了。
ora_parse ( $cursor , $query ) or die;
ora_exec ( $cursor );
ora_close ( $cursor );
ora_logoff ( $handle );
要執行 Oracle 的 SQL 指令前,要先經過 parse 的步驟。若在前面加上 @ (如: @ora_prase();),可以不讓用戶看到錯誤信息。在執行 query 指令後,就可以關閉與 Oracle 之間的連接了。
Header ( "Location: ./index.php" );
exit;
這二行讓浏覽器重定向到 index.php。讓用戶看到他的新留言,就完成了留言的步驟。
之後來看看留言的内容顯示程序。
<html>
<head>
<meta content="text/html; charset=gb2312" http-equiv=Content-Type>
<title>留言闆</title>
</head>
<body bgcolor=ffffff>
<?php
//---------------------------
// 留言顯示程序 index.php
// Author: Wilson Peng
// Copyright (C) 2000
//---------------------------
$WebmasterIPArray = array(
"10.0.1.30" , // 管理人員(yuán)甲的機器 IP
"10.0.2.28" // 管理人員(yuán)乙的機器 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 );
$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 );
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 ). ">下(xià)頁></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>
在顯示留言的部份,考慮到留言内容若很多,加上網絡慢(màn)的話(huà),可能會讓用戶在線路慢(màn)的時候拖累整個數據庫,因此,盡快的連上數據庫,取得需要的資(zī)料後,馬上關閉數據庫,再慢(màn)慢(màn)送給用戶,應是最好的對策。
程序分(fēn)成四部份
初始化
取數據庫中(zhōng)的資(zī)料
計算要顯示的頁數
送出資(zī)料
$WebmasterIPArray = array(
"10.0.1.30" , // 管理人員(yuán)甲的機器 IP
"10.0.2.28" // 管理人員(yuán)乙的機器 IP
);
$WebmasterIP = false ;
for ( $i = 0 ; $i < Count ( $WebmasterIPArray ); $i ++) {
if ( $REMOTE_ADDR == $WebmasterIPArray [ $i ]) $WebmasterIP = true ;
}
// 之後初始化 Oracle 程序略
顯示程序和留言程序的初始化部份都差不多,但顯示程序多加了一(yī)個功能,配置 Webmaster 的電腦。将 Webmaster 使用的 IP Address 加在 $WebmasterIPArray 數組變量中(zhōng),可以在顯示留言時,顯示删除留言的字符串,方便處理不當的留言。
$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 數據庫,将留言的資(zī)料取出放(fàng)在 $guestbook 數組中(zhōng)。取得資(zī)料後,就趕緊将數據庫關閉,再來處理 $guestbook 數組的資(zī)料了。
if ( $QUERY_STRING != "" ) {
$page = $QUERY_STRING ;
} else {
$page = 0 ;
}
這一(yī)段程序判斷是要顯示第幾頁,默認值是顯示第一(yī)頁。要顯示第三頁的頁面,需要使用 http://xxxxxx/index.php?2 的格式,也就是傳入 $QUERY_STRING,餘類推。之後的數行程序,都是用來處理顯示的頁數及筆數的資(zī)料。
$msgnum = 20 ; // 每頁二十筆
要改變每頁的顯示筆數,可以改 $msgnum 變量。程序的默認值爲 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" ;
}
這一(yī)段程序就是真正顯示留言資(zī)料給用戶看的程序了。利用 for 循環,将 $guestbook 數組的資(zī)料按照配置的頁數取出,顯示給用戶看。值得一(yī)提的是,若看留言的機器 IP 爲 $WebmasterIPArray 變量數組中(zhōng)的一(yī)個元素的話(huà),則會在留言者的匿稱後顯示 "删除本篇!!" 的字符串,供管理人員(yuán)删除不當留言。
以下(xià)即爲删除留言的程序。
<?php
//---------------------------
// 留言删除程序 erase.php
// Author: Wilson Peng
// Copyright (C) 2000
//---------------------------
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" );
?>
其實這個程序很單純,隻要打開(kāi) Oracle 數據庫,将要删除的序号那筆資(zī)料的 flag 字段設成 0 就可以了,不用将資(zī)料真的從數據庫上移除。
文章來源:http://www.adminlm.net/jc/php/200609/20155.html
免責聲明:本站相關技術文章信息部分(fēn)來自網絡,目的主要是傳播更多信息,如果您認爲本站的某些信息侵犯了您的版權,請與我(wǒ)(wǒ)們聯系,我(wǒ)(wǒ)們會即時妥善的處理,謝謝合作!