`
yeyuan
  • 浏览: 227087 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

discuz X1.5 DB类分析

阅读更多
class DB
{
	/*获取表名*/
	function table($table) {
		return DB::_execute('table_name', $table);
	}
	/*删除*/
	function delete($table, $condition, $limit = 0, $unbuffered = true) {
		if(empty($condition)) {
			$where = '1';//表达式为空,则where 1 网上有这方面的说明,不过我还没看懂什么意思,1=1为永真,1<>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" : '');//生成sql语句
		return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));//执行
	}
	/*插入*/
	function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false) {

		$sql = DB::implode_field_value($data);//分隔数组

		$cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';//选择是replace into 或 insert into

		$table = DB::table($table); //获取表
		$silent = $silent ? 'SILENT' : '';//这个是指查询类型,一般分两种mysql_query和mysql_unbuffered_query,默认为mysql_query

		$return = DB::query("$cmd $table SET $sql", $silent);//生成sql语句

		return $return_insert_id ? DB::insert_id() : $return;//返回新插入的行的id

	}
	/*更新*/
	function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {
		$sql = DB::implode_field_value($data);//分隔数组
		//low_priority意为低优先级,在网上大致查了下,意思是它的优先级不会高于读操作
		//假如在写的时候,有一个读的操作,那么系统允许,把读操作插入到写前面,等读完了,再写
		$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' : '');//生成sql语句
		return $res;//返回执行结果
	}
	/*分隔数组*/
	function implode_field_value($array, $glue = ',') {
		$sql = $comma = '';
		foreach ($array as $k => $v) {
			$sql .= $comma."`$k`='$v'";
			$comma = $glue;
		}
		return $sql;
	}
	/*获取插入新行的id*/
	function insert_id() {
		return DB::_execute('insert_id');
	}
	/*生成关联数组*/
	function fetch($resourceid, $type = MYSQL_ASSOC) {
		return DB::_execute('fetch_array', $resourceid, $type);
	}
	/*获取结果集中的第一行数据*/
	function fetch_first($sql) {
		DB::checkquery($sql);
		return DB::_execute('fetch_first', $sql);
	}
	/*返回结果集中的某一行*/
	function result($resourceid, $row = 0) {
		return DB::_execute('result', $resourceid, $row);
	}
	/*返回结果集中的第一行*/
	function result_first($sql) {
		DB::checkquery($sql);
		return DB::_execute('result_first', $sql);
	}
	/*执行查询*/
	function query($sql, $type = '') {
		DB::checkquery($sql);//过滤sql语句
		return DB::_execute('query', $sql, $type);
	}
	/*select语句查询所影响的行数*/
	function num_rows($resourceid) {
		return DB::_execute('num_rows', $resourceid);
	}
	/*update,insert,delete语句所影响的行数*/
	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');
	}
	//DB::_execute('table_name', $table)
	//相当于$res = $db->table_name($table);
	function _execute($cmd , $arg1 = '', $arg2 = '') {
		static $db;
		if(empty($db)) $db = & DB::object();//创建db_mysql对象
		$res = $db->$cmd($arg1, $arg2);
		return $res;
	}
	/*实例化db_mysql对象*/
	function &object() {
		static $db;
		if(empty($db)) $db = new db_mysql();
		return $db;
	}
	/*检查sql语句*/
	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;
	}
	/*过滤sql语句*/
	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;

	}

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics