最全discuz X2 DB数据库类详细说明

discuzX 系列的db数据库类写的已经非常好了,从性能、安全性和易用性上都做的非常优秀了。
了解discuzX 系列的db数据库类,不仅可以使我们能快速上手二次开发,也可以移植到自己的项目中来。

下面我们来分析讲解一下db数据类:

 <?php
class DB
{
 /**
  * 返回表名(pre_$table)
  *
  * @param 原始表名 $table
  * @return 增加pre之后的名字
  */ function table($table) {
  return DB::_execute('table_name', $table);
 }
 
 /**
  * 删除一条或者多条记录
  *
  * @param string $table 原始表名
  * @param string $condition 数组的形式,条件语句,不需要写WHERE
  * @param int $limit 删除条目数
  * @param boolean $unbuffered 可以参考php自带的mysql_unbuffered_query()函数
  */ function delete($table, $condition, $limit = 0, $unbuffered = true) {
  if(empty($condition)) {
   $where = '1';
  } elseif(is_array($condition)) {
   $where = DB::implode_field_value($condition, ' AND ');
  } else {
   $where = $condition;
  }
  $sql = "DELETE FROM ".DB::table($table)." WHERE $where ".($limit ? "LIMIT $limit" : '');
  return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));
 }
 
 /**
  * 插入一条记录
  *
  * @param string $table 原始表名
  * @param array $data 数组field->vlaue 对
  * @param boolen $return_insert_id 返回 InsertID?
  * @param boolen $replace 是否是REPLACE模式
  * @param boolen $silent 静默方式?
  * @return InsertID or Result
  */ function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false) {

  $sql = DB::implode_field_value($data);

  $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';

  $table = DB::table($table);
  $silent = $silent ? 'SILENT' : '';

  $return = DB::query("$cmd $table SET $sql", $silent);

  return $return_insert_id ? DB::insert_id() : $return;

 }

 /**
  * 更新一条或者多条数据记录
  *
  * @param string $table 原始表名
  * @param array $data 数据field-value
  * @param string $condition 条件语句,不需要写WHERE
  * @param boolean $unbuffered
  * @param boolan $low_priority mysql语法,UPDATE的执行被延迟了,直到没有其它的客户端从表中读取为止
  * @return result
  */ function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {
  $sql = DB::implode_field_value($data);
  $cmd = "UPDATE ".($low_priority ? 'LOW_PRIORITY' : '');
  $table = DB::table($table);
  $where = '';
  if(empty($condition)) {
   $where = '1';
  } elseif(is_array($condition)) {
   $where = DB::implode_field_value($condition, ' AND ');
  } else {
   $where = $condition;
  }
  $res = DB::query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');
  return $res;
 }
 
 /**
  * 格式化field字段和value,并组成一个字符串
  *
  * @param array $array 格式为 key=>value 数组
  * @param 分割符 $glue
  * @return string
  */ function implode_field_value($array, $glue = ',') {
  $sql = $comma = '';
  foreach ($array as $k => $v) {
   $sql .= $comma."`$k`='$v'";
   $comma = $glue;
  }
  return $sql;
 }
 
 /**
  * 返回插入的ID
  *
  * @return int
  */ function insert_id() {
  return DB::_execute('insert_id');
 }

 /**
  * 依据查询结果,返回一行数据,类似 mysql_fetch_array
  *
  * @param resourceID $resourceid
  * @return array
  */ function fetch($resourceid, $type = MYSQL_ASSOC) {
  return DB::_execute('fetch_array', $resourceid, $type);
 }

 /**
  * 依据SQL,返回一条查询结果 跟fetch一样,只是不做循环
  *
  * @param string $query 查询语句
  * @return array
  */ function fetch_first($sql) {
  DB::checkquery($sql);
  return DB::_execute('fetch_first', $sql);
 }
 
 /**
  * 依据查询结果,返回结果数值
  *
  * @param resourceid $resourceid
  * @return string or int 返回结果个数 0为1个
  */ function result($resourceid, $row = 0) {
  return DB::_execute('result', $resourceid, $row);
 }
 
 /**
  * 依据查询语句,返回一个结果数值
  *
  * @param string $query SQL查询语句
  * @return unknown
  */ function result_first($sql) {
  DB::checkquery($sql);
  return DB::_execute('result_first', $sql);
 }
 
 /**
  * 执行查询
  *
  * @param string $sql
  * @param 类型定义 $type UNBUFFERED OR SILENT
  * @return Resource OR Result
  */ function query($sql, $type = '') {
  DB::checkquery($sql);
  return DB::_execute('query', $sql, $type);
 }
 
 /**
  * 返回select的结果行数
  *
  * @param resource $resourceid
  * @return int
  */ function num_rows($resourceid) {
  return DB::_execute('num_rows', $resourceid);
 }

 /**
  * 返回sql语句所影响的记录行数
  *
  * @return int
  */ function affected_rows() {
  return DB::_execute('affected_rows');
 }
 
 /**
  * 释放结果内存 类似mysql_free_result
  *
  * @return int
  */ function free_result($query) {
  return DB::_execute('free_result', $query);
 }

 /**
  * mysql_error 返回上一个 MySQL 操作产生的文本错误信息
  *
  * @return string
  */ function error() {
  return DB::_execute('error');
 }

 /**
  * mysql_errno 返回上一个 MySQL 操作中的错误信息的数字编码
  *
  * @return string
  */ function errno() {
  return DB::_execute('errno');
 }
 
 /**
  * 与db_mysql类方法调用的桥梁
  * @param string $cmd 要调用的方法
  * @param string $arg1
  * @param string $arg2
  * @return unknown
  */ function _execute($cmd , $arg1 = '', $arg2 = '') {
  static $db;
  if(empty($db)) $db = & DB::object();
  $res = $db->$cmd($arg1, $arg2);
  return $res;
 }
 
 /**
  * 实例数据库类 支持多数据 默认mysql
  *
  * @return pointer of db object from discuz core
  */ function &object($dbclass = 'db_mysql') {
  static $db;
  if(empty($db)) $db = new $dbclass();
  return $db;
 }

 /**
  * sql查询语法 安全检查
  * @param unknown_type $sql
  * @return boolean
  */ function checkquery($sql) {
  static $status = null, $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');
  if($status === null) $status = getglobal('config/security/querysafe/status');
  if($status) {
   $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
   if(in_array($cmd, $checkcmd)) {
    $test = DB::_do_query_safe($sql);
    if($test < 1) DB::_execute('halt', 'security_error', $sql);
   }
  }
  return true;
 }
 
 /**
  * 估计是防注入检查
  * @param unknown_type $sql
  * @return string|number
  */ function _do_query_safe($sql) {
  static $_CONFIG = null;
  if($_CONFIG === null) {
   $_CONFIG = getglobal('config/security/querysafe');
  }

  $sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);
  $mark = $clean = '';
  if(strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false) {
   $clean = preg_replace("/'(.+?)'/s", '', $sql);
  } else {
   $len = strlen($sql);
   $mark = $clean = '';
   for ($i = 0; $i <$len; $i++) {
    $str = $sql[$i];
    switch ($str) {
     case '\'':
      if(!$mark) {
       $mark = '\'';
       $clean .= $str;
      } elseif ($mark == '\'') {
       $mark = '';
      }
      break;
     case '/':
      if(empty($mark) && $sql[$i+1] == '*') {
       $mark = '/*';
       $clean .= $mark;
       $i++;
      } elseif($mark == '/*' && $sql[$i -1] == '*') {
       $mark = '';
       $clean .= '*';
      }
      break;
     case '#':
      if(empty($mark)) {
       $mark = $str;
       $clean .= $str;
      }
      break;
     case "\n":
      if($mark == '#' || $mark == '--') {
       $mark = '';
      }
      break;
     case '-':
      if(empty($mark)&& substr($sql, $i, 3) == '-- ') {
       $mark = '-- ';
       $clean .= $mark;
      }
      break;

     default:

      break;
    }
    $clean .= $mark ? '' : $str;
   }
  }

  $clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));

  if($_CONFIG['afullnote']) {
   $clean = str_replace('/**/','',$clean);
  }

  if(is_array($_CONFIG['dfunction'])) {
   foreach($_CONFIG['dfunction'] as $fun) {
    if(strpos($clean, $fun.'(') !== false) return '-1';
   }
  }

  if(is_array($_CONFIG['daction'])) {
   foreach($_CONFIG['daction'] as $action) {
    if(strpos($clean,$action) !== false) return '-3';
   }
  }

  if($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {
   return '-2';
  }

  if(is_array($_CONFIG['dnote'])) {
   foreach($_CONFIG['dnote'] as $note) {
    if(strpos($clean,$note) !== false) return '-4';
   }
  }

  return 1;

 }

}
?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注