【discuzX2】/source/class/class_core.php文件中数据库操作类DB及db_mysql分析
2013-08-09 10:37
781 查看
<?php /** * 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 < 1) DB::_execute('halt', 'security_error', $sql); } } 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 <$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; } } ?>
相关文章推荐
- 【discuzX2】/source/class/class_core.php文件中数据库操作类DB及db_mysql分析
- 【discuzX2】/source/class/class_core.php文件中核心基础类库中discuz_core类分析
- 【discuzX2】/source/class/class_core.php文件中session会话类discuz_session分析
- 【discuzX2】/source/class/class_core.php文件中核心高效缓存类discuz_memory分析
- 【discuzX2】/source/class/class_core.php文件中session会话类discuz_session分析
- 【discuzX2】/source/class/class_core.php文件中核心高效缓存类discuz_memory分析
- 【discuzX2】/source/class/class_core.php文件中核心基础类库中discuz_core类分析
- 【discuzX2】/source/function/function_core.php通用核心函数库文件分析
- UCHome中数据库操作类(class_mysql.php)页面的代码分析
- 【discuzX2】/source/function/function_core.php通用核心函数库文件分析
- DiscuzX /source/function/function_core.php通用核心函数库文件分析
- 【thinkphp3.x】ThinkPHP/Lib/Core/Model.class.php文件分析
- 【phpcms-v9】phpcms-v9数据源调用的控制器文件分析phpcms/modules/dbsource/call.php
- 【thinkphp3.x】ThinkPHP/Lib/Core/View.class.php文件分析
- 【thinkphp3.x】ThinkPHP/Lib/Core/Dispatcher.class.php文件分析
- DISCUZX2.0 核心文件 class_core.php 分析之 – discuz_process
- 【thinkphp3.x】ThinkPHP/Lib/Core/App.class.php文件分析
- 【phpcms-v9】phpcms-v9数据源调用的控制器文件分析phpcms/modules/dbsource/call.php
- 【thinkphp3.x】ThinkPHP/Lib/Core/Think.class.php文件分析
- 将数据库常用的操作(连接数据库,获得所有数据,获得一条记录,获得一列记录,获得一条索引数组,获得一条关联数组)都给封装到db.class.php里面,谁需要谁继承这个类 注意:提交封装的类文件