discuz db_mysql.calss.php_【discuzX2】/source/class/class_core.php文件中数据库操作类DB及db_mysql分析...

/**

* Discuz MySQL 类的支持 程序中一般不直接使用此类,而是使用DB类,DB类对db_mysql类中的方法又进行了二次封装

*

*/

class db_mysql

{

var $tablepre;

var $version = '';

var $querynum = 0;

var $slaveid = 0;

var $curlink;

var $link = array();

var $config = array();

var $sqldebug = array();

var $map = array();

function db_mysql($config = array()) {

if(!empty($config)) {

$this->set_config($config);

}

}

function set_config($config) {

$this->config = &$config;

$this->tablepre = $config['1']['tablepre'];

if(!empty($this->config['map'])) {

$this->map = $this->config['map'];

}

}

function connect($serverid = 1) {

if(empty($this->config) || empty($this->config[$serverid])) {

$this->halt('config_db_not_found');

}

$this->link[$serverid] = $this->_dbconnect(

$this->config[$serverid]['dbhost'],

$this->config[$serverid]['dbuser'],

$this->config[$serverid]['dbpw'],

$this->config[$serverid]['dbcharset'],

$this->config[$serverid]['dbname'],

$this->config[$serverid]['pconnect']

);

$this->curlink = $this->link[$serverid];

}

function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {

$link = null;

$func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';

if(!$link = @$func($dbhost, $dbuser, $dbpw, 1)) {

$this->halt('notconnect');

} else {

$this->curlink = $link;

if($this->version() > '4.1') {

$dbcharset = $dbcharset ? $dbcharset : $this->config[1]['dbcharset'];

$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';

$serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';

$serverset && mysql_query("SET $serverset", $link);

}

$dbname && @mysql_select_db($dbname, $link);

}

return $link;

}

function table_name($tablename) {

if(!empty($this->map) && !empty($this->map[$tablename])) {

$id = $this->map[$tablename];

if(!$this->link[$id]) {

$this->connect($id);

}

$this->curlink = $this->link[$id];

return $this->config[$id]['tablepre'].$tablename;

} else {

$this->curlink = $this->link[1];

}

return $this->tablepre.$tablename;

}

function select_db($dbname) {

return mysql_select_db($dbname, $this->curlink);

}

function fetch_array($query, $result_type = MYSQL_ASSOC) {

return mysql_fetch_array($query, $result_type);

}

function fetch_first($sql) {

return $this->fetch_array($this->query($sql));

}

function result_first($sql) {

return $this->result($this->query($sql), 0);

}

function query($sql, $type = '') {

if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {

$starttime = dmicrotime();

}

$func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?

'mysql_unbuffered_query' : 'mysql_query';

if(!($query = $func($sql, $this->curlink))) {

if(in_array($this->errno(), array(2006, 2013)) && substr($type, 0, 5) != 'RETRY') {

$this->connect();

return $this->query($sql, 'RETRY'.$type);

}

if($type != 'SILENT' && substr($type, 5) != 'SILENT') {

$this->halt('query_error', $sql);

}

}

if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {

$this->sqldebug[] = array($sql, number_format((dmicrotime() - $starttime), 6), debug_backtrace());

}

$this->querynum++;

return $query;

}

function affected_rows() {

return mysql_affected_rows($this->curlink);

}

function error() {

return (($this->curlink) ? mysql_error($this->curlink) : mysql_error());

}

function errno() {

return intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());

}

function result($query, $row = 0) {

$query = @mysql_result($query, $row);

return $query;

}

function num_rows($query) {

$query = mysql_num_rows($query);

return $query;

}

function num_fields($query) {

return mysql_num_fields($query);

}

function free_result($query) {

return mysql_free_result($query);

}

function insert_id() {

return ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);

}

function fetch_row($query) {

$query = mysql_fetch_row($query);

return $query;

}

function fetch_fields($query) {

return mysql_fetch_field($query);

}

function version() {

if(empty($this->version)) {

$this->version = mysql_get_server_info($this->curlink);

}

return $this->version;

}

function close() {

return mysql_close($this->curlink);

}

function halt($message = '', $sql = '') {

require_once libfile('class/error');

discuz_error::db_error($message, $sql);

}

}

/**

* 对Discuz CORE 中 DB Object中的主要方法进行二次封装,方便程序调用

*

*/

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 立即返回?

*/

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 延迟更新?

* @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');

}

/**

* 依据查询结果,返回一行数据

*

* @param resourceID $resourceid

* @return array

*/

function fetch($resourceid, $type = MYSQL_ASSOC) {

return DB::_execute('fetch_array', $resourceid, $type);

}

/**

* 依据SQL语句,返回第一条查询结果

*

* @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

*/

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');

}

function free_result($query) {

return DB::_execute('free_result', $query);

}

function error() {

return DB::_execute('error');

}

function errno() {

return DB::_execute('errno');

}

function _execute($cmd , $arg1 = '', $arg2 = '') {//DB类中的很多方法都调用了此方法,此方法又调用了 &object()方法,详情请查看&object()方法,其实&object()方法返回一个db_mysql类的实例化对象,而且是statics类型的实例化对象

static $db;

if(empty($db)) $db = & DB::object();//返回db_mysql操作类的实例化对象

$res = $db->$cmd($arg1, $arg2);

return $res;

}

/**

* 返回 DB object 指针

*

* @return pointer of db object from discuz core

*/

function &object($dbclass = 'db_mysql') {

static $db;

if(empty($db)) $db = new $dbclass();//返回db_mysql数据库操作类的一个statics类型的实例化对象

return $db;

}

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 

}

}

return true;

}

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 

$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;

}

}

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值