zhg1983
金牌会员
 
初级会员
UID 65483
精华
0
积分 1259
帖子 77
金钱 1259 喜悦币
威望 0
人脉 0
阅读权限 70
注册 2005-8-4
状态 离线
|
我新写的文本数据库类,欢迎大家拍砖
以前刚开始学php的时候,自己没电脑,用的都是没有数据库的空间,所以对文本数据库熟悉了一些。不过以前用的都是用' | '分隔、用' \n '换行的文本数据库,每次都要读出文件,重新构造数组,太麻烦了。
所以在以前接触到serialize函数时,就有了写个新文本数据库类的想法,前几天有空就写出来,让大家拍拍砖。说实话,真的是第一次写类。
简单说明一下:
1、不需要重新构造数组,就是用了serialize和unserialize两个数组,或者说把构造数组的工作给这两个函数做吧,数组的结构如下:
Array
(
[field] => Array
(
[0] => fieldname1
[1] => fieldname2
[2] => fieldname3
)
[data] => Array
(
[1] => Array
(
[ fieldname1] => value1f1
[ fieldname2] => value1f2
[ fieldname3] => value1f3
)
[2] => Array
(
[ fieldname1] => value2f1
[ fieldname2] => value2f2
[ fieldname3] => value2f3
)
...
[AutoID] => Array
(
[ fieldname1] => ..
[ fieldname2] => ..
[ fieldname3] => ..
)
...
)
)
AutoID是系统自增的,也是唯一的;操作数据时直接使用键值为' data '的数组就可以了
2、还开发了一点类似于SQL中WHERE子句的功能,详见程序注释
3、由于以后不太用文本数据库了,所以没有继续将这个类完善,很多功能没有添加:比如类似于SQL中' ORDER BY '的子句的功能,有兴趣的继续哈
代码如下:
<?php /*----------------------- author:zhoujun-_-@163.com ------------------------*/
class TextDB { var $BasePath = './TextDB/'; //数据库根目录 var $TableFileExt = 'tdb'; //表的扩展名,复杂点可能会安全点吧 var $AutoIDStart = 1; //数据记录自增ID的开始值 var $DBPath; //当前数据库路径 var $AffectedRows; //UpdateRecord,DeleteRecord 所影响到的记录条数 var $SelectedRows; //SelectRecord 得到的记录条数
function TextDB() { ! is_dir($this->BasePath) && $this->ErrorMsg("数据库根目录不存在"); }
/*----------------------- name:CreateDB,创建数据库 para: dbname,数据库名 ------------------------*/ function CreateDB($dbname) { $newdb = $this->BasePath.$dbname; is_dir($newdb) && $this->ErrorMsg("数据库已经存在"); ! mkdir($newdb) && $this->ErrorMsg("创建数据库失败"); ! chmod($newdb,0777) && $this->ErrorMsg("新建数据库不能写入"); return true; }
/*----------------------- name:SelectDB,选择数据库,以后的操作都是这个数据库下的表 para: dbname,数据库名 ------------------------*/ function SelectDB($dbname) { $this->DBPath = $this->BasePath.$dbname."/"; ! is_dir($this->DBPath) && $this->ErrorMsg("数据库不存在"); }
/*----------------------- name:DeleteDB,删除数据库,并删除该数据库下所有表 para: dbname,数据库名 ------------------------*/ function DeleteDB($dbname) { $this->SelectDB($dbname); if ($dh = opendir($this->DBPath)) { while (false !== ($file = readdir($dh))) { if('.' == $file || '..' == $file) continue; unlink($this->DBPath.$file); } closedir($dh); } if(! rmdir($this->DBPath)) $this->ErrorMsg("数据库删除失败"); else return true; }
function GetTableFile($table) { ! $this->DBPath && $this->ErrorMsg("请选择数据库"); return $this->DBPath.$table.'.'.$this->TableFileExt; }
function CheckTableFile($table) { $tablefile = $this->GetTableFile($table); ! file_exists($tablefile) && $this->ErrorMsg("该表不存在"); return $tablefile; }
function WriteTableFile($tablefile,$str) { $fp = @fopen($tablefile,'w'); ( !flock($fp,LOCK_EX) || !@fwrite($fp,$str) ) && $this->ErrorMsg("表数据写入失败"); fclose($fp); }
/*----------------------- name:CreateTable,创建新表 para: table,新表的表名 field,表的字段名,必须为数组:array('fieldname1','fieldname2','fieldname3', ...) ------------------------*/ function CreateTable($table,$field) { $tablefile = $this->GetTableFile($table); $rec = array(); $rec['field'] = $field; $rec['data'] = array(); $str = serialize($rec); file_exists($tablefile) && $this->ErrorMsg("该表已存在"); ! touch($tablefile) && $this->ErrorMsg("表创建失败"); ! chmod($tablefile,0777) && $this->ErrorMsg("创建的表不能写"); $this->WriteTableFile($tablefile,$str); return true; }
/*----------------------- name:DeleteTable,删除表 para: table,表名 ------------------------*/ function DeleteTable($table) { $tablefile = $this->CheckTableFile($table); ! unlink($tablefile) && $this->ErrorMsg("删除表失败"); return true; }
function CheckWhereStr($str) { if('*' == $str) return "$check = 1;"; $exestr = "$check = ( "; $arr = explode(",",$str); $counter = count($arr); for($i=0;$i<$counter;$i++) { preg_match_all("/S+/",$arr[$i],$out); 3 != count($out[0]) && $this->ErrorMsg("查询参数有错误"); if('AutoID' == $out[0][0]) $arrname = "k"; else $arrname = "v['".$out[0][0]."']"; if('=' == $out[0][1]) $exestr .= " $".$arrname." == '".$out[0][2]."' "; elseif('LIKE' == $out[0][1]) $exestr .= " false !== strpos($".$arrname.",'".$out[0][2]."') "; elseif('!='==$out[0][1] || '>'==$out[0][1] || '<'==$out[0][1] || '>='==$out[0][1] || '<='==$out[0][1]) $exestr .= " $".$arrname." ".$out[0][1]." '".$out[0][2]."' "; $i < ($counter - 1) && $exestr .= " && "; } $exestr .= " );"; return $exestr; }
/*----------------------- name:InsertRecord,新增一条记录 para: table,表名 newdata,新的数据,必须为数组,键值为字段名:$newdata['fieldname1']=value1;$newdata['fieldname2']=value2... ------------------------*/ function InsertRecord($table,$newdata) { $tablefile = $this->CheckTableFile($table); $str = file_get_contents($tablefile); $rec = unserialize($str); $field = $rec['field']; $data = $rec['data']; $newrec = array(); foreach($field as $k => $v) { $newrec[$v] = $newdata[$v]; } if(0 == count($data)) { $data[$this->AutoIDStart] = $newrec; } else { $data[] = $newrec; } $rec['data'] = $data; $str = serialize($rec); unset($rec,$data,$field); $this->WriteTableFile($tablefile,$str); return true; }
/*----------------------- name:DeleteRecord,删除记录 para: table,表名 type和detailstr,查询的类型和查询的条件,type有两个值:'WHERE','QUICKID',对应的detailstr的格式也不同; type为'WHERE'时,detailstr格式为:'fieldname1 LIKE str1',必须以空格隔开,LIKE处还可以是'=,!=,>=,<=,>,<', 如果有多个条件,用','隔开,如:'fieldname1 LIKE str1,fieldname2 = str2,fieldname3 > str3', ','相当于SQL里的'AND',这里不支持类似SQL里'OR'的功能,有兴趣的可以继续, 如果要取得所有记录,detailstr 等于 '*' 就可以了, 条件中如果用到系统自增ID,用AutoID作为字段名,如:'AutoID > num1,AutoID < num2' 只有当你知道记录的确切ID(仅指系统自增的ID)的时候,用type='QUICKID',这样就不必遍历整个数组,可以提高效率, 如果有多个ID,用','隔开,如:'3,25' ------------------------*/ function DeleteRecord($table,$type,$detailstr) { $this->AffectedRows = 0; $tablefile = $this->CheckTableFile($table); $str = file_get_contents($tablefile); $rec = unserialize($str); $data = $rec['data']; if('QUICKID' == $type) { $idarr = explode(",",$detailstr); foreach($idarr as $v) { $v = intval($v); if(isset($data[$v])) { $this->AffectedRows ++; unset($data[$v]); } } } elseif('WHERE' == $type) { $exestr = $this->CheckWhereStr($detailstr); foreach($data as $k => $v) { eval($exestr); if($check) { $this->AffectedRows ++; unset($data[$k]); } } } $rec['data'] = $data; $str = serialize($rec); unset($rec,$data); $this->WriteTableFile($tablefile,$str); return true; }
/*----------------------- name:SelectRecord,查询记录 para: table,表名 needfield,要取的字段,多个字段用','隔开,如:'fieldname1,fieldname2,...';选所有字段则 needfield 等于 '*' type和detailstr,参考 DeleteRecord 的注释 ------------------------*/ function SelectRecord($table,$needfield,$type,$detailstr) { $tablefile = $this->CheckTableFile($table); $str = file_get_contents($tablefile); $rec = unserialize($str); $data = $rec['data']; if('*' == $needfield) $needfield = $rec['field']; else $needfield = explode(",",$needfield); $selectarr = array(); if('QUICKID' == $type) { $idarr = explode(",",$detailstr); foreach($idarr as $v) { $v = intval($v); if(isset($data[$v])) { $temp = array(); foreach($needfield as $vv) { $temp[$vv] = $data[$v][$vv]; } $selectarr[$v] = $temp; } } } elseif('WHERE' == $type) { $exestr = $this->CheckWhereStr($detailstr); foreach($data as $k => $v) { eval($exestr); if($check) { $temp = array(); foreach($needfield as $vv) { $temp[$vv] = $v[$vv]; } $selectarr[$k] = $temp; } } } $this->SelectedRows = count($selectarr); return $selectarr; } /*----------------------- name:UpdateRecord,更新记录 para: table,表名 newdata,更新的数据,必须为数组,键值为字段名:$newdata['fieldname1']=value1;$newdata['fieldname2']=value2... type和detailstr,参考 DeleteRecord 的注释 ------------------------*/ function UpdateRecord($table,$newdata,$type,$detailstr) { $this->AffectedRows = 0; $tablefile = $this->CheckTableFile($table); $str = file_get_contents($tablefile); $rec = unserialize($str); $data = $rec['data']; if('QUICKID' == $type) { $idarr = explode(",",$detailstr); foreach($idarr as $v) { $v = intval($v); if(isset($data[$v])) { foreach($newdata as $kk => $vv) { isset($data[$v][$kk]) && $data[$v][$kk] = $vv; } $this->AffectedRows ++; } } } elseif('WHERE' == $type) { $exestr = $this->CheckWhereStr($detailstr); foreach($data as $k => $v) { eval($exestr); if($check) { foreach($newdata as $kk => $vv) { isset($v[$kk]) && $data[$k][$kk] = $vv; } $this->AffectedRows ++; } } } $rec['data'] = $data; $str = serialize($rec); unset($rec,$data); $this->WriteTableFile($tablefile,$str); return true; }
/*--------- Error ----------*/ function ErrorMsg($msg) { echo $msg; exit; }
/*-------------------- 查看表中的所有数据,以及AffectedRows和SelectedRows,可以自己修改、完善 ---------------------*/ function Debug($table) { $tablefile = $this->CheckTableFile($table); $str = file_get_contents($tablefile); $rec = unserialize($str); echo "<hr><font color=red>Debug:</font>n<pre>"; echo "AffectedRows:".$this->AffectedRows."n"; echo "SelectedRows:".$this->SelectedRows."n"; print_r($rec); echo "</pre><hr>"; } } ?>
附件: 您所在的用户组无法下载或查看附件
|
|