在PHP中使用DBM作為數(shù)據(jù)庫
發(fā)表時間:2024-02-06 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]在眾多CGI語言中,PHP以其簡單,快速的優(yōu)點開始逐漸成長,使用PHP開發(fā)程序的人也越來越多,而一般PHP用的數(shù)據(jù)庫就兩種:文本以及MYSQL。文本數(shù)據(jù)庫讀、寫速度慢,當數(shù)據(jù)到達一定量時就會大大的降低速度乃至崩潰!而MYSQL雖然速度快,功能強大,不過不是一般的業(yè)余愛號者所能用得起的,因為一般的免...
在眾多CGI語言中,PHP以其簡單,快速的優(yōu)點開始逐漸成長,使用PHP開發(fā)程序的人也越來越多,而一般PHP用的數(shù)據(jù)庫就兩種:文本以及MYSQL。文本數(shù)據(jù)庫讀、寫速度慢,當數(shù)據(jù)到達一定量時就會大大的降低速度乃至崩潰!而MYSQL雖然速度快,功能強大,不過不是一般的業(yè)余愛號者所能用得起的,因為一般的免費空間都不支持MYSQL(有主機的朋友就不要往下看了)
今天筆者介紹的是DBM數(shù)據(jù)庫,DBM是柏克萊大學發(fā)展的文件/文本型數(shù)據(jù)庫,在BSD系統(tǒng)中已經(jīng)安裝完畢,即使沒有安裝,在PHP4.03中也加入了DBM的支持。因此,在大部份支持PHP的空間中都支持DBM(支持PHP的空間詳見www.zphp.com)下面將分步介紹在PHP使用DBM做為數(shù)據(jù)庫:
一、判斷你的空間是否支持DBM的方法:
輸入下面的程序:
----------------------------------------------------
<?
echo dblist();
?>
----------------------------------------------------
保存為dbmtest.php,運行,看看是否輸出函數(shù)沒有定義,如果不是,恭喜……
二、PHP使用DBM的基本函數(shù):
1、int dbmopen(string filepath,string mode);
這個可以打開一個DBM數(shù)據(jù)庫,其中filepath為DBM數(shù)據(jù)庫的路徑,mode有4個參數(shù):"r"以只讀的方式打開數(shù)據(jù)庫;"w"以讀寫方式打開數(shù)據(jù)庫;"c"以讀寫方式打開數(shù)據(jù)庫,若不存在則建立;"n"刪去現(xiàn)有數(shù)據(jù)庫,以讀寫方式打開數(shù)據(jù)庫。
2、boolean dbmclose(int handle); 關(guān)閉一個已經(jīng)打開了的DBM數(shù)據(jù)庫,同時釋放handle。
3、string dbmfetch(int handle,string key); 取得已經(jīng)打開了的handle數(shù)據(jù)庫的key所對應(yīng)的值。
4、boolean dbmexists(int handle, string key); 判斷在已經(jīng)打開了的handle數(shù)據(jù)庫中是否存在key。
5、string dbmfirstkey(int handle); 取得已經(jīng)打開了的handle數(shù)據(jù)庫的物理第一個key。
6、string dbmnextkey(int handle,string key);
取得已經(jīng)打開了的handle數(shù)據(jù)庫中的key所對應(yīng)的下一個key(就是dbmnextkey和dbmfirstkey兩個函數(shù)實現(xiàn)了dbm的遍歷搜索!)
7、boolean dbminsert(int handle,string key,string value);
在已經(jīng)打開了的handle數(shù)據(jù)庫中插入一個key,其對應(yīng)的值為value,如果已經(jīng)存在key則返回false。
8、boolean dbmreplace(int handle, string key, string value);
在已經(jīng)打開了的handle數(shù)據(jù)庫中替換key所對應(yīng)的值成為value,如果不存在key則返回建立。
9、boolean dbmdelete(int handle,string key);在已經(jīng)打開了的handle數(shù)據(jù)庫中刪除key。
三、使用DBM的注意事項:
1、DBM數(shù)據(jù)庫不像SQL,它只有單純的key/Value的定位,如果你想儲存多種信息,只能將信息用一個分隔符來分開,如下(這里用“ !:! ”做分隔符)
Name !:! TelNo !:! MailAdd //分別儲存了名字、電話及郵箱
讀取時方法如下:
----------------------------------------------------
$data=explode(' !:! 'dbmfetch($dbmid,$key));
//則$data[o]對應(yīng)名字,$data[1]對應(yīng)電話,$data[2]對應(yīng)郵箱
----------------------------------------------------
2、DBM本身儲存數(shù)據(jù)沒有任何物理順序,只能通過自己的處理(見下文)來排序!
3、DBM不像文本,把一個db從這個主機轉(zhuǎn)移到另一個主機上是會出錯的,即一旦建立一個db文件,就不能轉(zhuǎn)移!
4、DBM在NT下面一個key對應(yīng)的值的長度不能超過1k個字符,故在NT下不能使用DBM保留一些有長度問題的東西!
5、關(guān)于DBM中使用中文的KEY:DBM的key不能使用中文,筆者在一共程序中試過,如果使用中文作為key的話當key一多(大約20)就會出現(xiàn)無法遍歷搜索的問題!
四、用DBM做無序數(shù)據(jù)庫:
用DBM做無序數(shù)據(jù)庫(即數(shù)據(jù)無順序概念)十分簡單,比文本數(shù)據(jù)庫要簡單的多!比如下面是一個讓用戶輸入用戶名后給出用戶電話的程序:
----------------------------------------------------
<?
if(isset($userid)){
$data=dbmopen("path","r");
if(dbmexists($data,$userid))echo $no=dbmfetch($data,$userid);
else echo "UserID Error!";
dbmclose($data);
}else{
?>
請輸入您的用戶名:
<form action=<?echo$PHP_SELF;?>
<input type="text" name="userid">
<input type="submit" name="submit"></form><?}?>
----------------------------------------------------
五、用DBM做有序數(shù)據(jù)庫:
因為DBM沒有對數(shù)據(jù)進行排序,所以對于一些按一定順序輸出的程序(如剛才的程序改為顯示所有用戶的電話)則比較棘手,需要人為排序,下面筆者給出兩種方法:
1、排序數(shù)據(jù)法:在這種方法里我們專門用一個key所對應(yīng)的值來記錄順序,那個key我們?nèi)藶槊麨閟ort,sort對應(yīng)值如下:
data1's key data2's key data3's key ........ data n's key
其中data n's dey的長度需要一定(筆者使用的是時間方法,如下程序可以生成key:)
----------------------------------------------------
function getkey(){
$date=date("ymdHis");
return $date;
}
----------------------------------------------------
這樣用getkey()可以得到一個類似001203114950的12位key,而每個key就對應(yīng)它自己的值(在這里用戶的電話);而用substr($sort,$i*13,12)就可以讀出第i個用戶的key,下面是顯示列表的代碼:
----------------------------------------------------
<?
//首先要知道有多少個用戶,可以專門開一個num來記錄
$data=dbmopen("path","r"); //打開數(shù)據(jù)庫
$sort=dbmfetch($data,"sort"); //讀取sort
for($i=0;$i<$totaluser;$i++){
$key=substr($sort,$i*13,12); //安順序取得key
$telno=dbmfetch($data,$key); //讀出key對應(yīng)的value
echo $i+1." User's TelNO is ".$telno."<br>";
}
dbmclose($data);
?>
----------------------------------------------------
2、數(shù)組排序法:在這里感謝無傷兄,是他讓筆者想起用數(shù)組來排序的。數(shù)組排序的基本原理是將整個DBM數(shù)據(jù)庫的每條key讀入數(shù)組,然后根據(jù)每個key的大小使用usort()等函數(shù)排序然后輸出。
因為是對key的大小排序,所以key的長度沒有什么限制,只要保證后加入的key大于先加入的key就可以實現(xiàn)先顯示后加入的人,這里用time()來作為key。
下面是列表代碼:
----------------------------------------------------
$data=dbmopen("path","r"); //打開數(shù)據(jù)庫
$i=1;
for($key=dbmfirstkey($data);$key;$key=dbmnextkey($data,$key)){
$sort[$i]=$key;
$i++;
} //遍歷取得所有的key
usort($sort); //安大小排序
for($i=0;$i<count($sort);$i++)
echo $i+1." User's TelNO is ".dbmfetch($data,$sort[$i])."<br>";
dbmclose($data);
----------------------------------------------------
以上兩種方法在運行時占用內(nèi)存(用于排序)第一種比第二種要大一點,不過對于運算量來講,第一種方法則要小于第二種,至于想用哪種方法就隨你意了(如果你興趣,可以試試兩者的CPU占用率)。
筆者在經(jīng)過了N次(N>50)實驗后完成了這篇文章僅以此獻給窮苦的仍在用txt的朋友們相信也不是所有看CN的人都有自己的主機!如果有什么不明白的,來這里看看:www.zphp.com。
筆者不是什么高手,不過因為幾乎找不到在PHP上使用DBM數(shù)據(jù)庫的資料(包括英文資料,不過Perl方面的卻不少)。最好留一個筆者用DBM寫的論壇,大家可以試試速度:www.zphp.com/demo/dbmbbs/ !