先说明,如果自己就能那么轻松写一个和mysql的数据库。那人家还混吗?下面有一个类自己看吧!
<?php
/*
This TextData Class txtTbl writen by ridge.jiang [email protected] and finished in 2003.01.01
Your can copy and use it without agreedment,It's free. But you can't use it for busness using.
You are also wellcome to modify this code in your mind. Thank for your work and tell me.This class is for small information database so like classmater databse,they are less than 300 recorders.
If your want store and opreat more than 300 recorders,It's recommandly to use SQL server.Your may acess the Instance of this Class with bellow function,there recommandly Do NOT use
inner var and function,because that's unsafe.
create()
drop()
open()
close()
eof()
bof()
prev()
next()
first()
end()fieldsCount()
getValue()
setValue()display()
location()recNO()
recCount()del()
append()*/
define ("tblPath",".\\");
define ("exten",".php");
define ("fileHead","<? echo \"You are wellcome!\"?".">This file only for class txtTbl");
class txtTbl {
  var $innerName="";  //数据库名称
  var $innerCount;  //数据库记录数目
  var $innerFields;  //数据库字段列表数组
  var $inner_F_Count; //数据库字段数目
  var $fullName;  //完整的文件名
  var $isModify = false;  //当前记录是否被修改
  var $fileModify = false;  //数据库是否被修改
  var $innerRecorders;  //数据库记录数组
  var $curLine;  //当前记录号
  var $curArray;  //当前行数组
  var $stringDel;  //保存被删除记录
  var $sprt1;  //数据库记录间的分隔符
  var $sprt2;  //数据库字段间的分隔符
  var $innerBof = true;
  var $innerEof = false;   function create($tblName,$fields,$sprt1="<---txtTbl--->\n",$sprt2="<---txtTbl--->"){
 if (empty($tblName)){
  echo "The textDateBase file name not appoint.";
  return false;
 }
 $fullName = tblPath.$tblName.exten;
    if (file_exists($fullName)){
  echo "The textDateBase file is already exist.";
  return false;
 }
    if(empty($fields)){
  echo "The fields list Array is invalid.";
  return false;
 }
 $cont = implode($sprt2,$fields);
 $cont = fileHead."\n".$cont;
 $fp = fopen($fullName,"w");
    fwrite($fp,$cont);
 fclose($fp);
 return true;
  }  function drop($tblName,$sprt1="<---txtTbl--->\n",$sprt2="<---txtTbl--->"){
 if (empty($tblName)){
  echo "The textDateBase file name not proveid.";
  return false;
 }
 if (!empty($this->innerName)){
  echo "Current file not closed,Please close it and try again.";
  return false;
 }
 $fullName = tblPath.$tblName.exten;
    if (!file_exists($fullName)){
  echo "The textDateBase file not exist.";
  return false;
 }
 $fp = fopen($fullName,"r");
 if (!feof($fp)){
  $readFromFile = fgets($fp);
 }
 if ($readFromFile!=fileHead."\n"){
  fclose($fp);
  echo "not a valid textDataBase file.(the head is invalid.)"."\n";
  return false;
 }
 $readFromFile = "";
 if (!feof($fp)) $readFromFile.= fgets($fp);
 fclose($fp);
 $readFromFile = trim($readFromFile);
 if (empty($readFromFile)){
  echo "not a valid textDataBase file.(can't find fields define.)";
  return false;
 }
 $cont = fileHead."\n".$readFromFile;
 $fp = fopen($fullName,"w");
 fwrite($fp,$cont);
 fclose($fp);
 return true;
  }
  
  
  function open($tblName,$sprt1="<---txtTbl--->\n",$sprt2="<---txtTbl--->"){
 if (empty($tblName)){
  echo "The textDateBase file name not proveid.";
  return false;
 }
 if (!empty($this->innerName)){
  echo "Current file not closed,Please close it and try again.";
  return false;
 }
 $this->fullName = tblPath.$tblName.exten;
    if (!file_exists($this->fullName)){
  echo "The textDateBase file not exist.";
  return false;
 }
 $fp = fopen($this->fullName,"r");
 if (!feof($fp)){
  $readFromFile = fgets($fp);
 }
 if ($readFromFile!=fileHead."\n"){
  fclose($fp);
  echo "not a valid textDataBase file.(the head is invalid.)"."\n";
  return false;
 }
 $readFromFile = "";
 while (!feof($fp)) $readFromFile.= fgets($fp);
 fclose($fp);
 $readFromFile = trim($readFromFile);
 if (empty($readFromFile)){
  echo "not a valid textDataBase file.(can't find fields define.)";
  return false;
 }
    $this->innerRecorders = explode($sprt1,$readFromFile);
 $this->innerCount = count($this->innerRecorders) - 1;
    $this->innerFields = explode($sprt2,$this->innerRecorders[0]);
    $this->innerFieldsCount = count($this->innerFields); $this->innerName = $tblName;
 $this->sprt1 = $sprt1;
 $this->sprt2 = $sprt2; if ($this->innerCount==0){
  $this->curLine = 0;
  $this->innerEof = true;
 }else{
  $this->curLine = 1;
//  if ($this->innerCount==1) $this->innerEof = true;
        if (!$this->initRec()) return false;
 } return true;
  }  function close(){
 if (empty($this->innerName)) return true;
 //save modify
 $isModify= false;
    if ($this->isModify){
  $this->saveModify();
  $isModify= true;
 }
 if(isset($this->stringDel)){
  $isModify= true;
  $delNo= explode(",",$this->stringDel);
  foreach($delNo as $no){
   $no= (integer) $no;
   unset($this->innerRecorders[$no]);
  }
 }
 if ($isModify||$this->fileModify){
  $recorders= implode($this->sprt1,$this->innerRecorders);
  $recorders= fileHead."\n".$recorders;
  $fp = fopen($this->fullName,"w");
  fwrite($fp,$recorders);
  fclose($fp);
 }
 $this->innerName="";
 unset($this->innerRecorders);
 unset($this->curArray);
  }  function next(){
   if ((!$this->innerEof)&&(!empty($this->innerName))){
    if($this->curLine==$this->innerCount){
     $this->innerEof = true;
     return true;
    }
    $this->saveModify();
    $this->curLine++;
    if ($this->innerBof) $this->innerBof = false;
    $this->initRec();
   }
   return false;
  }
  
  function prev(){
   if ((!$this->innerBof)&&(!empty($this->innerName))){
    $this->saveModify();
    $this->curLine--;
    if ($this->curLine == 1)
     $this->innerBof = true;
    if ($this->innerEof) $this->innerEof = false;
    $this->initRec();
   }
  }  function first(){
    if ($this->innerBof||empty($this->innerName))
  return false;
    $this->saveModify();
 $this->curLine = 1;
 $this->innerBof= true;
 $this->innerEof = false;
 $this->initRec();
 
  }
  
  function end(){
    if ($this->innerEof||empty($this->innerName))
  return false;
    $this->saveModify();
 $this->curLine = $this->innerCount;
 $this->innerEof= true;
 $this->innerBof = false;
 $this->initRec();
 
  }

解决方案 »

  1.   


      function eof(){
       if (empty($this->innerName)){
        return false;
       }else return $this->innerEof;
      }  function bof(){
       if (empty($this->innerName)){
        return true;
       }else return $this->innerBof;
      }  function recNo(){
       return $this->curLine;
      }  function recCount(){
       return $this->innerCount;
      }  function fieldsCount(){
       if (empty($this->innerName)){
        return false;
       }else return $this->inner_F_Count;
      }  function getValue($field){
     if ($this->curLine==0||empty($this->innerName)){
      echo "Can't read current record,maybe not in use or no record.";
      return false;
     }
     $field= $this->chkField($field);
        if ($field==-1){
      return false;
     }
     return $this->curArray[$field];
      }  
      function setValue($field,$value){
        if ($this->curLine==0||empty($this->innerName)){
      echo "Can't read current record,maybe not in use or no record.";
      return false;
     }
     $field= $this->chkField($field);
     if ($field==-1){
      return false;
     }
     $this->curArray[$field]= $value;
     $this->modify= true;
      }
      
      function display($shownon=0,$sprt1="<td>",$sprt2="</td>",$sprt3="<tr>",$sprt4="</tr>"){
     echo $sprt3;
     foreach($this->curArray as $v){
      if($shownon==1&&empty($v)) $v= "noValue";
      echo $sprt1.$v.$sprt2;
     }
     echo $sprt4;
      }  function location($field,$keyValue){
        $field=$this->chkField($field);
     if ($field==-1) return false;
     for($i=$this->curLine;$i<=$this->innerCount;$i++){
      if($this->curArray[$field]==$keyValue){
       return true;
      }
      $this->next();
     }
     return false;
      }
      
      function del($recNo=-1){
     if($this->curLine==0) return false;
     $vartype= gettype($recNo);
     if($vartype!="integer"){
      echo "del error:check ur para type.";
      return false;
     }
        if ($recNo==-1){
      $recNo=$this->curLine;}
     elseif ($recNo>$this->innerCount||$recNo<1){
      echo "del error:out over the rang.";
      return false;
     }
     if (!$this->chkDel($recNo)){
      if(isset($this->stringDel)){
       $this->stringDel.=(','.$recNo);
      }else $this->stringDel = (string) $recNo;
     }else return false;
      }
       
      function append($fields=""){
     $this->saveModify();
     for($i=1;$i<=$this->innerFieldsCount;$i++)
      $newRec[] = "";
        if(!empty($fields)){
      foreach($fields as $k=>$v){
       $k= $this->chkField($k);
       if ($k==-1){
        return false;
       }
                $newRec[$k]= $v;
      }
     }
     $this->innerCount++;
     $this->curLine = $this->innerCount;
     $this->innerBof = false;
     $this->innerEof = true;
     unset($this->curArray);
     $this->curArray = &$newRec;
     $this->isModify = true;
      }
     
     //保存修改
     function saveModify(){
      if($this->isModify){
       $this->innerRecorders[$this->curLine]= implode($this->sprt2,$this->curArray);
       $this->isModify = false;
       $this->fileModify= true;
      }
     } //当指针发生变化时,初始化当前记录数组
     function initRec(){
      $this->curArray = explode($this->sprt2,$this->innerRecorders[$this->curLine]);
      if (count($this->curArray)!=$this->innerFieldsCount){
       echo "The Current Recorder fields count unequal to Table's.\n File will close.";
       $this->close();
       return false;
      }
      return true;
     }
     //输出当前记录信息,设计为调试用
     function ddisplay(){
      if ($this->innerCount==0) return false;
      foreach($this->innerFields as $v) echo $v."----";
      echo "<br>";
      foreach($this->curArray as $v) echo $v."---";
     } //检查记录是否已被删除
     function chkDel($key){
      if (empty($key)&&$key!=0){
       echo "the key not appoint.";
       return false;
      }
      if (!isset($this->stringDel)){
       return false;
      }
      if (ereg("(^|,)".$key."(,|$)",$this->stringDel)){
       return true;
      }
      return false;
     } //检查提交的字段名是否合法.
     function chkField($field){
      if (empty($field)&&($field!=0)){
       echo "the field not appoint.";
       return -1;
      }
      $vartype = gettype($field);
      switch ($vartype) {
       case "integer":
        if ($field>=$this->innerFieldsCount){
            echo "the field is large than fieldscount";
            return -1;
        }elseif($field<0){
         echo "the field is less than 0";
         return -1;
        }
        return $field;
      case "string":
       foreach ($this->innerFields as $k=>$v) if ($field==$v) return $k;
       echo "the field name not found.";
       return -1;
      default:
       echo "the field is invalid.";
       return -1;
      }
     }}
    ?>续上,太长了。只能分开贴。
      

  2.   

    小意思
    http://www.dev-club.com/club/bbs/showEssence.asp?id=18267
      

  3.   

    from CTB,中国文本论坛的典范!看看它的代码,非常的好!class CtbClass { var $file;    
    var $index;      //建立一个文件并写入输入
    function null_write($new)
    {
    $f=fopen($this->file,"w");    
    flock($f,LOCK_EX);
    fputs($f,$new);    
    fclose($f); 
    }
    // 添加数据记录到文件末端
    function add_write($new) {     
    $f=fopen($this->file,"a");    
    flock($f,LOCK_EX);
    fputs($f,$new);     
    fclose($f); 

    // 配合readfile()的返回一起使用,把一行数据转换为一维数组
    function make_array($line) {
    $array = explode("\x0E",$line);
    return $array;
    }

    //把为一维数组转换一行数据
    function join_array($line) {
    $array = join("\x0E",$line);
    return $array;
    }
    // 返回数据文件的总行数
    function getlines() {
    $f=file($this->file);    
    return count($f);    
    }
    // 返回下一行的数据记录(备用)
    function next_line() {
    $this->index=$this->index++;    
    return $this->get();    
    } // 返回上一行的数据记录(备用)
    function prev_line() {
    $this->index=$this->index--;    
    return $this->get();    
    }  
    // 返回当前行的数据记录数据较小
    function get() {
    $f=fopen($this->file,"r");    
    flock($f,LOCK_SH);
    for($i=0;$i<=$this->index;$i++) {
    $rec=fgets($f,1024);    
    }
    $line=explode("\x0E",$rec);
    fclose($f);
    return $line;    
    }  
    // 返回当前行的数据记录数据较大
    function get_big_file() {
    $f=fopen($this->file,"r");    
    flock($f,LOCK_SH);
    for($i=0;$i<=$this->index;$i++) {
    $rec=fgets($f,1024*5);    
    }
    $line=explode("\x0E",$rec);
    fclose($f);
    return $line;    
    }  
    // 打开数据文件---以一维数组返回文件内容
    function read_file() {
    if (file_exists($this->file)) {
    $line =file($this->file);
    }
    return $line;
    }
    // 打开数据文件---以二维数组返回文件内容
    function openFile() {
    if (file_exists($this->file)) {
    $f =file($this->file);
    $lines = array();
    foreach ($f as $rawline) {
    $tmpline = explode("\x0E",$rawline);
    array_push($lines, $tmpline);
    }
    }
    return $lines;
    }
    // 传入一个数组,合并成一行数据,重写整个文件
    function overwrite($array){
    $newline = implode("\x0E",$array);
    $f = fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newline);
    fclose($f);
    }
      
    // 添加一行数据记录到文件末端
    function add_line($array,$check_n=1) {  
    $s=implode("\x0E",$array);    
    $f=fopen($this->file,"a");    
    flock($f,LOCK_EX);
    fputs($f,$s);    
    if ($check_n==1) fputs($f,"\n");    
    fclose($f); 
    }     // 插入一行数据记录到文件最前面
    function insert_line($array) {
    $newfile = implode("\x0E",$array);
    $f = fopen($this->file,"r");
    flock($f,LOCK_SH);
    while ($line = fgets($f,1024)) {
    $newfile .= $line;
    }
    fclose($f);
    $f = fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newfile);
    fclose($f);
    } // 更新所有符合条件的数据记录,适用于每行字节数据较大的情况
    function update($column,$query_string,$update_array) {
    $update_string = implode("\x0E",$update_array);   
    $newfile = "";
    $fc=file($this->file);
    $f=fopen($this->file,"r");
    flock($f,LOCK_SH);
    for ($i=0;$i<count($fc);$i++) {
    $list = explode("\x0E",$fc[$i]);
    if ($list[$column] != $query_string) {
    $newfile = $newfile.chop($fc[$i])."\n";
    } else {
    $newfile = $newfile.$update_string;
    }
    }
    fclose($f);
    $f=fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newfile);
    fclose($f);
    } // 更新所有符合条件的数据记录,适用于每行字节数据较小的情况
    function update2($column,$query_string,$update_array) {
    $newline = implode("\x0E",$update_array);   
    $newfile = "";
    $f = fopen($this->file,"r");
    flock($f,LOCK_SH);
    while ($line = fgets($f,1024)) {
    $tmpLine = explode("\x0E",$line);
    if ($tmpLine[$column] == $query_string) {
    $newfile .= $newline;
    } else {
    $newfile .= $line;
    }
    }
    fclose($f);
    $f = fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newfile);
    fclose($f);
    } // 删除所有符合条件的数据记录,适用于每行字节数据较大的情况
    function delete($column,$query_string) {
    $newfile = "";
    $fc=file($this->file);
    $f=fopen($this->file,"r");
    flock($f,LOCK_SH);
    for ($i=0;$i<count($fc);$i++) {
    $list = explode("\x0E",$fc[$i]);
    if ($list[$column] != $query_string) {
    $newfile = $newfile.chop($fc[$i])."\n";
    }
    }
    fclose($f);
    $f=fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newfile);
    fclose($f);
    }     // 删除所有符合条件的数据记录,适用于每行字节数据较小的情况
    function delete2($column,$query_string){  
    $newfile = "";
    $f = fopen($this->file,"r");
    flock($f,LOCK_SH);
    while ($line = fgets($f,1024)) {
    $tmpLine = explode("\x0E",$line);
    if ($tmpLine[$column] != $query_string) {
    $newfile .= $line;
    }
    }
    fclose($f);
    $f = fopen($this->file,"w");
    flock($f,LOCK_EX);
    fputs($f,$newfile);
    fclose($f);
    }    //取得一个文件里某个字段的最大值
    function get_max_value($column) {
    $tlines = file($this->file);
    for ($i=0;$i<=count($tlines);$i++) {
    $line=explode("\x0E",$tlines[$i]);
    $get_value[]=$line[$column];
    }
            $get_max_value = max($get_value);
    return $get_max_value;
    }
    // 根据数据文件的某个字段是否包含$query_string进行查询,以二维数组返回所有符合条件的数据
    function select($column, $query_string) {
    $tline = $this->openfile();
    $lines = array();
    foreach ($tline as $line) {
    if ($line[$column] == $query_string) {
    array_push($lines, $line);
    }
    } return $lines;
    } // 功能与function select()一样,速度可能略有提升
    function select2($column, $query_string) {
    if (file_exists($this->file)) {
    $tline = $this->read_file();
    foreach ($tline as $tmpLine) {
    $line = $this->make_array($tmpLine);
    if ($line[$column] == $query_string) {
    $lines[]=$tmpLine;
    }
    }
    } return $lines;
    } // 根据数据文件的某个字段是否包含$query_string进行查询,以一维数组返回第一个符合条件的数据
    function select_line($column, $query_string) {
    $tline = $this->read_file();
    foreach ($tline as $tmpLine) {
    $line = $this->make_array($tmpLine);
    if ($line[$column] == $query_string) {
            return $line;
    break;
    }
    }
    }
    // select next/prev line(next_prev ==> 1/next, 2/prev) by cx
    function select_next_prev_line($column, $query_string, $next_prev) {
    $tline = $this->read_file();
    $line_key_end = count($tline) - 1;
    $line_key = -1;
    foreach ($tline as $tmpLine) {
    $line_key++;
    $line = $this->make_array($tmpLine);
    if ($next_prev == 1) {  // next?
    if ($line[$column] == $query_string) {
    if ($line_key == 0) {
    return 0;
    } else {
    $line_key_up = $line_key - 1;
    return $up_line;
    }
    } else {
    $up_line = $line;
    }
    } elseif ($next_prev == 2) {  // prev?
    if ($line[$column] == $query_string) {
    if ($line_key == $line_key_end) {
    return 0;
    } else {
    $line_key_down = $line_key + 1;
    break;
    }
    }
    } else {
    return 0;
    }
    }
    $down_line = $this->make_array($tline[$line_key_down]);
    return $down_line;
    }}
      

  4.   

    纯php写的文本数据库并不适合于频繁的更新
    1、更新时需要读取整个文件到内存中,严重影响性能
    2、并发更新操作将会造成不可预料的后果,虽然理论上讲用文件锁可以达到独享操作,但是事实上却不是绝对的。我曾经写过一个文本留言板,就出现这种情况。如果是读取,并不建议采用file()方法,使用文档操作指针或逐行读取方法更利于系统性能。
      

  5.   

    不建议这样做法,对于操作文本而言,用自己定义的规则就行了,何苦跟着SQL走呢!
      

  6.   

    有些人肯定认为这没有什么必要,既然有SQL还用文本干什么?其实不尽然,当系统不能加数据库的时候不就的需要文本了,例如我们系统对稳定性要求极高的时候,例如半年不死,如果多一个数据库,会增加很多出错的机会的!不过我觉得要是很多用户使用的时候,频繁的操作文件一定很容易出问题,还好,我们的系统只能几个人使用。