您当前的位置:首页 > 网站建设笔记 >

discuzX3.3 db_driver_mysql.php文件代码注释

0
<?php
if (!defined('IN_DISCUZ')) {
	exit('Access Denied');
}
class db_driver_mysql
{
	var $tablepre;
	var $version = '';
	var $drivertype = 'mysql';
	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'];
			for ($i=1; $i<=100; $i++) {
				if (isset($this->map['forum_thread'])) {
					$this->map['forum_thread_'.$i] = $this->map['forum_thread'];
				}
				if (isset($this->map['forum_post'])) {
					$this->map['forum_post_'.$i] = $this->map['forum_post'];
				}
				if (isset($this->map['forum_attachment']) && $i <= 10) {
					$this->map['forum_attachment_'.($i-1)] = $this->map['forum_attachment'];
				}
			}
			if (isset($this->map['common_member'])) {
				$this->map['common_member_archive'] =
				$this->map['common_member_count'] = $this->map['common_member_count_archive'] =
				$this->map['common_member_status'] = $this->map['common_member_status_archive'] =
				$this->map['common_member_profile'] = $this->map['common_member_profile_archive'] =
				$this->map['common_member_field_forum'] = $this->map['common_member_field_forum_archive'] =
				$this->map['common_member_field_home'] = $this->map['common_member_field_home_archive'] =
				$this->map['common_member_validate'] = $this->map['common_member_verify'] =
				$this->map['common_member_verify_info'] = $this->map['common_member'];
			}
		}
	}
	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, $halt=true) {
		if ($pconnect) {
			$link = @mysql_pconnect($dbhost, $dbuser, $dbpw, MYSQL_CLIENT_COMPRESS);
		} else {
			//resource mysql_connect([string $server [,string $username [,string $password [,bool $new_link [,int $client_flags]]]]])
			//如果用同样的参数第二次调用 mysql_connect(),将不会建立新连接,而将返回已经打开的连接标识。参数 new_link 改变此行为并使 mysql_connect() 总是打开新的连接,甚至当 mysql_connect() 曾在前面被用同样的参数调用过。
			//MYSQL_CLIENT_COMPRESS	使用压缩的通讯协议
			$link = @mysql_connect($dbhost, $dbuser, $dbpw, 1, MYSQL_CLIENT_COMPRESS);
		}
		if (!$link) {
			$halt && $this->halt('notconnect', $this->errno());
		} 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];
		} else {
			$this->curlink = $this->link[1];
		}
		return $this->tablepre.$tablename;
	}
	function select_db($dbname) {
		return mysql_select_db($dbname, $this->curlink);
	}
//处理SELECT查询结果的主要工具是mysql_fetch_array(), 它带有一个查询结果变量(我曾称之为$result), 并以数组格式一次返回一行数据。
//你将希望在一个循环内使用这个函数,只要有更多的行,循环就会持续访问返回的每一行。从查询读取每条记录的基本构造如下:
//while($row = mysql_fetch_array($result)){//do something with $row}

//mysql_fetch_array()函数带有一个可选的参数, 用于指定返回的数组的类型: 联合数组、索引数组或者这两者。联合数组允许通过名称引用列值, 而索引数组则要求只使用数字(对于返回的第一列, 从0开始)。
	function fetch_array($query, $result_type=MYSQL_ASSOC) {
		return mysql_fetch_array($query, $result_type);
	}
//array mysql_fetch_row(resource $result)
//mysql_fetch_row()从和指定的结果标识关联的结果集中取得一行数据并作为数组返回。每个结果的列储存在一个数组的单元中,偏移量从0开始。
//依次调用mysql_fetch_row()将返回结果集中的下一行,如果没有更多行则返回FALSE。
	function fetch_row($query) {
		$query = mysql_fetch_row($query);
		return $query;
	}
	function fetch_first($sql) {
		return $this->fetch_array($this->query($sql));
	}
//一旦你成功地连接到并选择一个数据库,就可以开始执行查询。这些查询可以是诸如插入、更新和删除之类的基本查询,或者是返回许多行的复杂联结中所涉及的查询。
//无论如何,用于执行查询的PHP函数都是mysql_query():
//$result = mysql_query($query);

//对于像INSERT、UPDATE、DELETE等简单的查询(它们不会返回记录),$result变量将返回TRUE或FALSE,这取决于查询是否执行成功。对于确实会返回记录的复杂查询(SELECT、SHOW、DESCRIBE和EXPLAIN),如果查询有效,则$result变量将是一个指向查询结果的资源链接:如果查询无效,则$result变量将为FALSE。

	public function query($sql, $silent=false, $unbuffered=false) {
		if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
//mixed microtime([bool $get_as_float])
//microtime()当前Unix时间戳以及微秒数。本函数仅在支持gettimeofday()系统调用的操作系统下可用。
//如果调用时不带可选参数,本函数以 "msec sec" 的格式返回一个字符串,其中 sec 是自Unix纪元(0:00:00 January 1, 1970 GMT)起到现在的秒数,msec是微秒部分。字符串的两部分都是以秒为单位返回的。
//如果给出了 get_as_float 参数并且其值等价于TRUE,microtime()将返回一个浮点数。
			$starttime = microtime(true);
		}
//resource mysql_unbuffered_query(string $query [,resource $link_identifier])
//mysql_unbuffered_query()向MYSQL发送一条SQL查询query,但不像mysql_query()那样自动获取并缓存结果集。一方面,这在处理很大的结果集时会节省可观的内存。另一方面,可以在获取第一行后立即对结果集进行操作,而不用等到整个SQL语句都执行完毕。当使用多个数据库连接时,必须指定可选参数link_identifier。

//mysql_unbuffered_query()的好处是有代价的:在mysql_unbuffered_query()返回的结果集之上不能使用mysql_num_rows()和mysql_data_seek()。此外在向MySQL发送一条新的SQL查询之前,必须提取掉所有未缓存的SQL查询所产生的结果行。

		if('UNBUFFERED' === $silent) {
			$silent = false;
			$unbuffered = true;
		}elseif('SILENT' === $silent) {
			$silent = true;
			$unbuffered = false;
		}
		$func = $unbuffered ? 'mysql_unbuffered_query' : 'mysql_query';

//resource mysql_query(string $query [,resource $link_identifier = NULL])
//mysql_query()向与指定的 link_identifier 关联的服务器中的当前活动数据库发送一条查询(不支持多条查询)。
//参数query: SQL查询语句
//参数link_identifier: MySQL连接。如不指定连接标识,则使用由mysql_connect()最近打开的连接。如果没有找到该连接,会尝试不带参数调用mysql_connect()来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

//返回值: mysql_query()仅对SELECT, SHOW, DESCRIBE, EXPLAIN和其他语句返回一个resource, 如果查询出现错误则返回FALSE。
//对于其它类型的SQL语句,比如INSERT, UPDATE, DELETE, DROP之类,mysql_query()在执行成功时返回TRUE,出错时返回FALSE。

//返回的结果资源应该传递给mysql_fetch_array()和其他函数来处理结果表,取出返回的数据。
//假定查询成功,可以调用mysql_num_rows()来查看对应于SELECT语句返回了多少行,或者调用mysql_affected_rows()来查看对应于DELETE, INSERT, REPLACE, UPDATE语句影响到了多少行。

//如果没有权限访问查询语句中引用的表时,mysql_query()也会返回FALSE。

		if(!($query = $func($sql, $this->curlink))) {
//Error: 2013 (CR_SERVER_LOST)
//Message: Lost connection to MySQL server during query
//Error: 2006 (CR_SERVER_GONE_ERROR)
//Message: MySQL server has gone away
			if(in_array($this->errno(), array(2006, 2013)) && substr($silent, 0, 5) != 'RETRY') {
				$this->connect();
				return $this->query($sql, 'RETRY'.$silent);
			}
			if(!$silent) {
				$this->halt($this->error(), $this->errno(), $sql);
			}
		}
		if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
			$this->sqldebug[] = array($sql, number_format((microtime(true)-$starttime), 6), debug_backtrace(), $this->curlink);
		}
		$this->querynum++;
		return $query;
	}
//string mysql_error([resource $link_identifier])
//返回上一个MySQL函数的错误文本,如果没有出错则返回""(空字符串)。如果没有指定连接资源号,则使用上一个成功打开的连接从MySQL服务器提取错误信息。
//从MySQL数据库后端来的错误不再发出警告,要用mysql_error()来提取错误文本。注意本函数仅返回最近一次MySQL函数的执行(不包括mysql_error()和mysql_errno())的错误文本,因此如果要使用此函数,确保在调用另一个MySQL函数之前检查它的值。
	function error() {
		return (($this->curlink) ? mysql_error($this->curlink) : mysql_error());
	}
//int mysql_errno([resource $link_identifier])
//返回上一个MySQL函数的错误号码,如果没有出错则返回0。
//从MySQL数据库后端来的错误不再发出警告,要用mysql_errno()来提取错误代码。注意本函数仅返回最近一次MySQL函数的执行(不包括mysql_error()和mysql_errno())的错误代码,因此如果要使用此函数,确保在调用另一个MySQL函数之前检查它的值。
//如果指定了可选参数则用给定的连接提取错误代码。否则使用上一个打开的连接。
	function errno() {
		return intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());
	}
//int mysql_num_rows(resource $result)
//mysql_num_rows()返回结果集中行的数目。此命令仅对SELECT语句有效。要取得被INSERT, UPDATE或者DELETE查询所影响到的行的数目用mysql_affected_rows()。
	function num_rows($query) {
		$query = mysql_num_rows($query);
		return $query;
	}
//int mysql_affected_rows([resource $link_identifier = NULL])
//取得最近一次与link_identifier关联的INSERT, UPDATE或DELETE查询所影响的记录行数。
	function affected_rows() {
		return mysql_affected_rows($this->curlink);
	}
//bool mysql_free_result(resource $result)
//mysql_free_result()将释放所有与结果标识符result所关联的内存。
//mysql_free_result()仅需要在考虑到返回很大的结果集时会占用多少内存时调用。在脚本结束后所有关联的内存都会被自动释放。
//成功时返回TRUE,或者在失败时返回FALSE
	function free_result($query) {
		return mysql_free_result($query);
	}

//mixed mysql_result(resource $result, int $row [,mixed $field])
//mysql_result()返回MySQL结果集中一个单元的内容。字段参数可以是字段的偏移量或者字段名,或者是字段表点字段名(tablename.fieldname)。如果给列起了别名,则用别名替代列名。
	function result($query, $row=0) {
		$query = @mysql_result($query, $row);
		return $query;
	}
	function result_first($sql) {
		return $this->result($this->query($sql), 0);
	}
//int mysql_num_fields(resource $result)
//mysql_num_fields()返回结果集中字段的数目
	function num_fields($query) {
		return mysql_num_fields($query);
	}
//int mysql_insert_id([resource $link_identifier])
//mysql_insert_id()返回给定的 link_identifier 中上一步INSERT查询中产生的AUTO_INCREMENT的ID号。如果没有指定link_identifier,则使用上一个打开的连接。
//如果上一查询没有产生AUTO_INCREMENT的值,则mysql_insert_id()返回0。如果需要保存该值以后使用,要确保在产生了值的查询之后立即调用mysql_insert_id()。
	function insert_id() {
		return ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
	}
//object mysql_fetch_field(resource $result [,int $field_offset])
//mysql_fetch_field()可以用来从某个查询结果中取得字段的信息。如果没有指定字段偏移量,则下一个尚未被mysql_fetch_field()取得的字段被提取。
	function fetch_fields($query) {
		return mysql_fetch_field($query);
	}
//string mysql_get_server_info([resource $link_identifier])
//mysql_get_server_info()返回link_identifier所使用的服务器版本。如果省略link_identifier,则使用上一个打开的连接。
	function version() {
		if(empty($this->version)) {
			$this->version = mysql_get_server_info($this->curlink);
		}
		return $this->version;
	}
//string mysql_escape_string(string $unescaped_string)
//本函数将unescaped_string转义,使之可以安全用于mysql_query()
//mysql_escape_string()并不转义%和_,本函数和mysql_real_escape_string()完全一样,除了mysql_real_escape_string()接受的是一个连接句柄并根据当前字符集转移字符串之外。mysql_escape_string()并不接受连接参数,也不管当前字符集设定。
	function escape_string($str) {
		return mysql_escape_string($str);
	}
	function close() {
		return mysql_close($this->curlink);
	}
	function halt($message='', $code=0, $sql='') {
		throw new DbException($message, $code, $sql);
	}
}
?>

建站咨询

在线咨询真诚为您提供专业解答服务

咨询热线

137 1731 25507×24小时服务热线

微信交流

二维码终于等到你,还好我没放弃
返回顶部