MySQL Master/Slave数据库读写操作类
两年前写了一个 Master/Slave 的PHP操作类,一直没有更新,今天更新了一下。2006/09/20简单快速有趣的MySQL数据库操作类:SimpleDB
2007/07/30构建支持Master/Slave读写分离的数据库操作类
2009/11/17MySQL Master/Slave数据库读写操作类 (2009/11/17 updated)
// 开发作者: heiyeluren
// 版本历史:
// 2006-09-20基本单数据库操作功能, 25 个接口
// 2007-07-30支持单Master/多Slave数据库操作,29个接口
// 2008-09-07修正了上一版本的部分Bug
// 2009-11-17 在Master/Slave类的基础上增加了强化单主机操作,
// 增加了部分简洁操作接口和调试接口,优化了部分代码,
// 本版本共42个接口
数据库操作类:DBCommon.class.php
view plaincopy to clipboardprint?
$key = $value;
}
/**
* 读取类属性
*
* @param str $key需要读取的属性名
* @return void
*/
function get($key){
return $this->$key;
}
//------------------------
//
// 基础底层操作接口
//
//------------------------
/**
* 构造函数
*
* 传递配置信息,配置信息数组结构:
* $masterConf = array(
* "host" => Master数据库主机地址
* "user" => 登录用户名
* "pwd" => 登录密码
* "db" => 默认连接的数据库
* );
* $slaveConf = array(
* "host" => Slave1数据库主机地址|Slave2数据库主机地址|...
* "user" => 登录用户名
* "pwd" => 登录密码
* "db" => 默认连接的数据库
* );
*
* @param bool $singleHost是否只有一台主机
* @return void
*/
function DBCommon($masterConf, $slaveConf=array(), $singleHost = true){
//构造数据库配置信息
if (is_array($masterConf) && !emptyempty($masterConf)){
$this->wdbConf = $masterConf;
}
if (!is_array($slaveConf) || emptyempty($slaveConf)){
$this->rdbConf = $masterConf;
} else {
$this->rdbConf = $slaveConf;
}
$this->singleHost = $singleHost;
//初始化连接(一般不推荐)
if ($this->isInitConn){
$this->getDbWriteConn();
if (!$this->singleHost){
$this->getDbReadConn();
}
}
}
/**
* 获取Master的写数据连接
*/
function getDbWriteConn(){
//判断是否已经连接
if ($this->wdbConn && is_resource($this->wdbConn)) {
return $this->wdbConn;
}
//没有连接则自行处理
$db = $this->connect($this->wdbConf['host'], $this->wdbConf['user'], $this->wdbConf['pwd'], $this->wdbConf['db']);
if (!$db || !is_resource($db)) {
return false;
}
$this->wdbConn = $db;
return $this->wdbConn;
}
/**
* 获取Slave的读数据连接
*/
function getDbReadConn(){
//如果有可用的Slave连接,随机挑选一台Slave
if (is_array($this->rdbConn) && !emptyempty($this->rdbConn)) {
$key = array_rand($this->rdbConn);
if (isset($this->rdbConn[$key]) && is_resource($this->rdbConn[$key])) {
return $this->rdbConn[$key];
}
}
//连接到所有Slave数据库,如果没有可用的Slave机则调用Master
$arrHost = explode("|", $this->rdbConf['host']);
if (!is_array($arrHost) || emptyempty($arrHost)){
return $this->getDbWriteConn();
}
$this->rdbConn = array();
foreach($arrHost as $tmpHost){
$db = $this->connect($tmpHost, $this->rdbConf['user'], $this->rdbConf['pwd'], $this->rdbConf['db']);
if ($db && is_resource($db)){
$this->rdbConn[] = $db;
}
}
//如果没有一台可用的Slave则调用Master
if (!is_array($this->rdbConn) || emptyempty($this->rdbConn)){
$this->errorLog("Not availability slave db connection, call master db connection");
return $this->getDbWriteConn();
}
//随机在已连接的Slave机中选择一台
$key = array_rand($this->rdbConn);
if (isset($this->rdbConn[$key])&& is_resource($this->rdbConn[$key])){
return $this->rdbConn[$key];
}
//如果选择的slave机器是无效的,并且可用的slave机器大于一台则循环遍历所有能用的slave机器
if (count($this->rdbConn) > 1){
foreach($this->rdbConn as $conn){
if (is_resource($conn)){
return $conn;
}
}
}
//如果没有可用的Slave连接,则继续使用Master连接
return $this->getDbWriteConn();
}
/**
* 连接到MySQL数据库公共方法
*/
function connect($dbHost, $dbUser, $dbPasswd, $dbDatabase){
//连接数据库主机
$db = mysql_connect($dbHost, $dbUser, $dbPasswd);
if (!$db) {
$this->errorLog("Mysql connect ". $dbHost ." failed");
return false;
}
//选定数据库
if (!mysql_select_db($dbDatabase, $db)) {
$this->errorLog("select db $dbDatabase failed", $db);
return false;
}
//设置字符集
if ($this->isCharset){
if ( $this->dbVersion == '' ){
$res = mysql_query("SELECT VERSION()");
$this->dbVersion = mysql_result($res, 0);
}
if ($this->dbCharset!='' && preg_match("/^(5.|4.1)/", $this->dbVersion)){
if (mysql_query("SET NAMES '".$this->dbCharset."'", $db) === false){
$this->errorLog("Set db_host '$dbHost' charset=". $this->dbCharset ." failed.", $db);
return false;
}
}
}
return $db;
}
/**
* 关闭数据库连接
*/
function disconnect($dbConn=null, $closeAll=false){
//关闭指定数据库连接
if ($dbConn && is_resource($dbConn)){
mysql_close($dbConn);
$dbConn = null;
}
//关闭所有数据库连接
if ($closeAll){
if ($this->rdbConn && is_resource($this->rdbConn)){
mysql_close($this->rdbConn);
$this->rdbConn = null;
}
if (is_array($this->rdbConn) && !emptyempty($this->rdbConn)){
foreach($this->rdbConn as $conn){
if ($conn && is_resource($conn)){
mysql_close($conn);
}
}
$this->rdbConn = array();
}
}
return true;
}
/**
* 选择数据库
*/
function selectDb($dbName, $dbConn=null){
//重新选择一个连接的数据库
if ($dbConn && is_resource($dbConn)){
if (!mysql_select_db($dbName, $dbConn)){
$this->errorLog("Select database:$dbName failed.", $dbConn);
return false;
}
return true;
}
//重新选择所有连接的数据库
if ($this->wdbConn && is_resource($this->wdbConn)){
if (!mysql_select_db($dbName, $this->wdbConn)){
$this->errorLog("Select database:$dbName failed.", $this->wdbConn);
return false;
}
}
if (is_array($this->rdbConn && !emptyempty($this->rdbConn))){
foreach($this->rdbConn as $conn){
if ($conn && is_resource($conn)){
if (!mysql_select_db($dbName, $conn)){
$this->errorLog("Select database:$dbName failed.", $conn);
return false;
}
}
}
}
return true;
}
/**
* 执行SQL语句(底层操作)
*/
function _query($sql, $isMaster=false){
if (trim($sql) == ""){
$this->errorLog("Sql query is empty.");
return false;
}
//是否只有一台数据库机器
if ($this->singleHost){
$isMaster = true;
}
//获取执行SQL的数据库连接
if (!$isMaster){
$optType = trim(strtolower(substr(ltrim($sql), 0, 6)));
}
if ($isMaster || $optType!="select"){
$dbConn = $this->getDbWriteConn();
} else {
$dbConn = $this->getDbReadConn();
}
if (!$dbConn || !is_resource($dbConn)){
$this->isError = true;
$this->errMsg= 'Not availability db connection.';
$this->currConn = null;
$this->errorLog("Not availability db connection. Query SQL:". $sql);
if ($this->isExit) {
exit;
}
return false;
}
//记录执行的SQL
if ($this->logSqlLevel){
$isLog = false;
$logLevel = $this->logSqlLevel;
if ($logLevel==1 && in_array($optType, array('insert'))){
$isLog = true;
}
if ($logLevel==2 && in_array($optType, array('insert', 'update'))){
$isLog = true;
}
if ($logLevel==3 && in_array($optType, array('insert', 'update', 'delete'))){
$isLog = true;
}
if ($logLevel==4 && in_array($optType, array('insert', 'update', 'delete', 'select'))){
$isLog = true;
}
if ($isLog){
$this->errorLog($sql);
}
}
//执行查询
$this->currConn = $dbConn;
$this->dbSql = $sql;
$this->dbResult = null;
if ($this->isRuntime){
$startTime = $this->getTime();
$this->dbResult = @mysql_query($sql, $dbConn);
$this->runTime = $this->getTime() - $startTime;
} else {
$this->dbResult = @mysql_query($sql, $dbConn);
}
if ($this->dbResult === false){
$this->isError = true;
$this->errMsg= 'MySQL errno:'. mysql_errno($dbConn) .', error:'. mysql_error($dbConn);
$this->errorLog("Query sql failed. SQL:".$sql, $dbConn);
if ($this->isExit) {
exit;
}
return false;
}
$this->isError = false;
$this->errMsg= '';
return true;
}
/**
* 错误日志
*/
function errorLog($msg='', $conn=null){
if (!$this->isLog){
return;
}
if ($msg=='' && !$conn) {
return false;
}
$log = "MySQL Error: $msg";
if ($conn && is_resource($conn)) {
$log .= " mysql_msg:". mysql_error($conn);
}
$log .= " [". date("Y-m-d H:i:s") ."]";
if ($this->logFile != ''){
error_log($log ."\n", 3, $this->logFile);
} else {
error_log($log);
}
return true;
}
//--------------------------
//
// 数据获取接口
//
//--------------------------
/**
* 获取SQL执行的全部结果集(二维数组)
*
* @param string $sql 需要执行查询的SQL语句
* @return 成功返回查询结果的二维数组,失败返回false, 数据空返回NULL
*/
function getAll($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
while ($row = @mysql_fetch_array($this->dbResult, $this->fetchMode)) {
$this->dbRecord[] = $row;
}
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || emptyempty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取单行记录(一维数组)
*
* @param string $sql 需要执行查询的SQL语句
* @return 成功返回结果记录的一维数组,失败返回false, 数据空返回NULL
*/
function getRow($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
$this->dbRecord = @mysql_fetch_array($this->dbResult, $this->fetchMode);
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || emptyempty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取一列数据(一维数组)
*
* @param string $sql 需要获取的字符串
* @param string $field 需要获取的列,如果不指定,默认是第一列
* @return 成功返回提取的结果记录的一维数组,失败返回false, 数据空返回NULL
*/
function getCol($sql, $field='', $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
while($row = @mysql_fetch_array($this->dbResult, $this->fetchMode)){
if (trim($field) == ''){
$this->dbRecord[] = current($row);
} else {
$this->dbRecord[] = $row[$field];
}
}
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || emptyempty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取一个数据(当条数组)
*
* @param string $sql 需要执行查询的SQL
* @return 成功返回获取的一个数据,失败返回false, 数据空返回NULL
*/
function getOne($sql, $field='', $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
$row = @mysql_fetch_array($this->dbResult, $this->fetchMode);
@mysql_free_result($this->dbResult);
if (!is_array($row) || emptyempty($row)){
return NULL;
}
if (trim($field) != ''){
$this->dbRecord = $row[$field];
}else{
$this->dbRecord = current($row);
}
return $this->dbRecord;
}
/**
* 获取指定各种条件的记录
*
* @param string $table 表名(访问的数据表)
* @param string $field 字段(要获取的字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $order 排序(按照什么字段排序,不包括ORDER BY,默认为空)
* @param string $limit 限制记录(需要提取多少记录,不包括LIMIT,默认为空)
* @param bool $single 是否只是取单条记录(是调用getRow还是getAll,默认是false,即调用getAll)
* @return 成功返回记录结果集的数组,失败返回false
*/
function getRecord($table, $field='*', $where='', $order='', $limit='', $single=false, $isMaster=false){
$sql = "SELECT $field FROM $table";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= trim($order)!='' ? " ORDER BY $order " : $order;
$sql .= trim($limit)!='' ? " LIMIT $limit " : $limit;
if ($single){
return $this->getRow($sql, $isMaster);
}
return $this->getAll($sql, $isMaster);
}
/**
* 获取指点各种条件的记录(跟getRecored类似)
*
* @param string $table 表名(访问的数据表)
* @param string $field 字段(要获取的字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param array $order_arr 排序数组(格式类似于: array('id'=>true), 那么就是按照ID为顺序排序, array('id'=>false), 就是按照ID逆序排序)
* @param array $limit_arr 提取数据的限制数组()
* @return unknown
*/
function getRecordByWhere($table, $field='*', $where='', $arrOrder=array(), $arrLimit=array(), $isMaster=false){
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
if (is_array($arrOrder) && !emptyempty($arrOrder)){
$arrKey = key($arrOrder);
$sql .= " ORDER BY $arrKey " . ($arrOrder[$arrKey] ? "ASC" : "DESC");
}
if (is_array($arrLimit) && !emptyempty($arrLimit)){
$startPos = intval(array_shift($arrLimit));
$offset = intval(array_shift($arrLimit));
$sql .= " LIMIT $startPos,$offset ";
}
return $this->getAll($sql, $isMaster);
}
/**
* 获取指定条数的记录
*
* @param string $table 表名
* @param int $startPos 开始记录
* @param int $offset 偏移量
* @param string $field 字段名
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $order 排序(按照什么字段排序,不包括ORDER BY,默认为空)
* @return 成功返回包含记录的二维数组,失败返回false
*/
function getRecordByLimit($table, $startPos, $offset, $field='*', $where='', $oder='', $isMaster=false){
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= trim($order)!='' ? " ORDER BY $order " : $order;
$sql .= " LIMIT $startPos,$offset ";
return $this->getAll($sql, $isMaster);
}
/**
* 获取排序记录
*
* @param string $table 表名
* @param string $orderField 需要排序的字段(比如id)
* @param string $orderMethod 排序的方式(1为顺序, 2为逆序, 默认是1)
* @param string $field 需要提取的字段(默认是*,就是所有字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $limit 限制记录(需要提取多少记录,不包括LIMIT,默认为空)
* @return 成功返回记录的二维数组,失败返回false
*/
function getRecordByOrder($table, $orderField, $orderMethod=1, $field='*', $where='', $limit='', $isMaster=false){
//$order_method的值为1则为顺序, $order_method值为2则2则是逆序排列
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= " ORDER BY $orderField " . ( $orderMethod==1 ? "ASC" : "DESC");
$sql .= trim($limit)!='' ? " LIMIT $limit " : $limit;
return $this->getAll($sql, $isMaster);
}
/**
* 分页查询(限制查询的记录条数)
*
* @param string $sql 需要查询的SQL语句
* @param int $startPos 开始记录的条数
* @param int $offset 每次的偏移量,需要获取多少条
* @return 成功返回获取结果记录的二维数组,失败返回false
*/
function limit_query($sql, $startPos, $offset, $isMaster=false){
$start_pos = intval($startPos);
$offset = intval($offset);
$sql = $sql . " LIMIT $startPos,$offset ";
return $this->getAll($sql, $isMaster);
}
//--------------------------
//
// 无数据返回操作接口
//
//--------------------------
/**
* 执行执行非Select查询操作
*
* @param string $sql 查询SQL语句
* @return bool成功执行返回true, 失败返回false
*/
function execute($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
return true;
/*$count = @mysql_affected_rows($this->dbLink);
if ($count100, 'user' => 'heiyeluren')
* @param int $mode 执行操作的模式 (是插入还是更新操作, 1是插入操作Insert, 2是更新操作Update)
* @param string $where 如果是更新操作,可以添加WHERE的条件
* @return bool 执行成功返回true, 失败返回false
*/
function autoExecute($table, $arrField, $mode, $where='', $isMaster=false){
if ($table=='' || !is_array($arrField) || emptyempty($arrField)){
return false;
}
//$mode为1是插入操作(Insert), $mode为2是更新操作
if ($mode == 1){
$sql = " INSERT INTO `$table` SET ";
} elseif ($mode == 2) {
$sql = " UPDATE `$table` SET ";
} else {
$this->errorLog("Operate type '$mode' is error, in call DB::autoExecute process table $table.");
return false;
}
foreach ($arrField as $key => $value){
$sql .= "`$key`='$value',";
}
$sql = rtrim($sql, ',');
if ($mode==2 && $where!=''){
$sql .= "WHERE $where";
}
return $this->execute($sql, $isMaster);
}
/**
* 锁表表
*
* @param string $tblName 需要锁定表的名称
* @return mixed 成功返回执行结果,失败返回错误对象
*/
function lockTable($tblName){
return $this->_query("LOCK TABLES $tblName", true);
}
/**
* 对锁定表进行解锁
*
* @param string $tblName 需要锁定表的名称
* @return mixed 成功返回执行结果,失败返回错误对象
*/
function unlockTable($tblName){
return $this->_query("UNLOCK TABLES $tblName", true);
}
/**
* 设置自动提交模块的方式(针对InnoDB存储引擎)
* 一般如果是不需要使用事务模式,建议自动提交为1,这样能够提高InnoDB存储引擎的执行效率,如果是事务模式,那么就使用自动提交为0
*
* @param bool $autoCommit 如果是true则是自动提交,每次输入SQL之后都自动执行,缺省为false
* @return mixed 成功返回true,失败返回错误对象
*/
function setAutoCommit($autoCommit = false){
$autoCommit = ( $autoCommit ? 1 : 0 );
return $this->_query("SET AUTOCOMMIT = $autoCommit", true);
}
/**
* 开始一个事务过程(针对InnoDB引擎,兼容使用 BEGIN 和 START TRANSACTION)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function startTransaction(){
if (!$this->_query("BEGIN")){
return $this->_query("START TRANSACTION", true);
}
}
/**
* 提交一个事务(针对InnoDB存储引擎)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function commit(){
if (!$this->_query("COMMIT", true)){
return false;
}
return $this->setAutoCommit( true );
}
/**
* 发生错误,会滚一个事务(针对InnoDB存储引擎)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function rollback(){
if (!$this->_query("ROLLBACK", true)){
return false;
}
return $this->setAutoCommit( true );
}
//--------------------------
//
// 其他数据操作接口
//
//--------------------------
/**
* 获取上次插入操作的的ID
*
* @return int 如果没有连接或者查询失败,返回0, 成功返回ID
*/
function getLastId(){
$dbConn = $this->getDbWriteConn();
if (($lastId = mysql_insert_id($dbConn)) > 0){
return $lastId;
}
return $this->getOne("SELECT LAST_INSERT_ID()", '', true);
}
/**
* 获取记录集里面的记录条数 (用于Select操作)
*
* @return int 如果上一次无结果集或者记录结果集为空,返回0, 否则返回结果集数量
*/
function getNumRows($res=null){
if (!$res || !is_resource($res)){
$res = $this->dbResult;
}
return mysql_num_rows($res);
}
/**
* 获取受到影响的记录数量 (用于Update/Delete/Insert操作)
*
* @return int 如果没有连接或者影响记录为空, 否则返回影响的行数量
*/
function getAffectedRows(){
$dbConn = $this->getDbWriteConn();
if ( ($affetedRows = mysql_affected_rows($dbConn)) getOne("SELECT ROW_COUNT()", "", true);
}
//--------------------------
//
// 相应配合操作接口
//
//--------------------------
/**
* 获取最后一次查询的SQL语句
*
* @return string 返回最后一次查询的SQL语句
*/
function getLastSql(){
return $this->dbSql;
}
/**
* 返回SQL最后操作的数据库记录结果集
*
* @return mixed 最后结果集,可能是数组或者普通单个元素值
*/
function getDBRecord(){
return $this->dbRecord;
}
/**
* 获取当前操作的数据库连接资源
*
* @return resouce 返回当前正在执行操作的数据库链接资源
*/
function getCurrConnection(){
return $this->currConn;
}
/**
* SQL 执行是否出错
*
* @return bool
*/
function isError(){
return $this->isError;
}
/**
* SQL 执行错误消息
*
* @return string
*/
function getError(){
return $this->errMsg;
}
/**
* 获取执行时间
*
* @return float
*/
function getRunTime(){
if ($this->isRuntime){
return sprintf("%.6f sec",$this->runTime);
}
return 'NULL';
}
/**
* 获取当前时间函数
*
* @param void
* @return float $time
*/
function getTime(){
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
//--------------------------
//
// 开发调试监控接口
//
//--------------------------
/**
* 调试信息内部输出接口
*
* @param string $title 需要输出的标题
* @param array $index 需要输出的内容数组(二维数组)
* @return void
*/
function _debug_print_table($title, $index, $content_pre = false){
echo "".$title."\n";
//二维数组
if (isset($index)){
echo "";
foreach($index as $k => $v){
echo "$k";
}
echo "";
foreach($index as $v){
echo "";
foreach($v as $_v){
$_v = $_v == NULL ? ' ' : $_v;
echo !$content_pre ? "$_v" : "$_v";
}
echo "";
}
echo "
";
}
//一维数组
else {
echo "";
foreach($index as $k => $v){
echo "$k";
}
echo "";
foreach($index as $k => $v){
$v = $v == NULL ? ' ' : $v;
echo !$content_pre ? "$v" : "$v";
}
echo "
";
}
}
/**
* 输出数据表结构信息
*
* @param void
* @return void
*/
function debug_table_info($table_name = ''){
$curr_sql = $this->getLastSql();
//SQL性能信息
echo "
";
$explain = $this->getAll("explain ".$curr_sql);
if (!emptyempty($explain)){
$this->_debug_print_table('SQL Explain:', $explain);
}
//总体SQL详细操作性能信息
$version = $this->getOne("select version()");
if (preg_match("/^(5.)/", $version) && substr($version,0,6) >= '5.0.37'){
if ($this->execute("set profiling = 1")){
$this->execute($curr_sql);
$index = $this->getAll("show profile cpu,block io,memory,swaps for query 1");
$this->execute("set profiling = 0");
$this->_debug_print_table("SQL Performance Profiling:", $index);
$index = $this->getAll("show profiles");
$this->_debug_print_table("", $index);
}
}
//获取刚才操作的表名
$table_name = isset($explain) ? $explain['table'] : $explain['table'];
if ($table_name == ''){
return;
}
//索引列表
$index = $this->getAll("show index from $table_name");
$this->_debug_print_table("Table '$table_name' Index:", $index);
//表结构
$index = $this->getAll("desc $table_name");
$this->_debug_print_table("Table '$table_name' Fileds:", $index);
//创建表语句
$explain = $this->getRow("show create table $table_name");
if (!emptyempty($explain)){
$this->_debug_print_table("Table '$table_name' Create:", $explain, true);
}
}
/**
* 输出数据库服务器运行信息
*
* @param void
* @return void
*/
function debug_server_info(){
echo "
";
//进程信息
$index = $this->getAll("show full processlist");
$this->_debug_print_table("Database Process List", $index);
//变量信息
$index = $this->getAll("show global variables");
$this->_debug_print_table("Database Variables List", $index);
//状态信息
$index = $this->getAll("show global status");
$this->_debug_print_table("Database Status Info", $index);
//服务器打开表信息
$index = $this->getAll("show open tables");
$this->_debug_print_table("Database Open tables List", $index);
}
/**
* 输出所有类属性和值
*
* @return void
*/
function debug_class_var(){
$class = get_class($this);
//其他类属性
echo "
$class Attribute: \n";
echo "
";
$vars = get_object_vars($this);
print_r($vars);
echo "\n
";
}
/**
* 输出所有类方法名
*
* @return void
*/
function debug_class_method() {
$class = get_class($this);
$arr = get_class_methods($class);
echo "$class method list
\n";
foreach ($arr as $method) {
echo "\t$method()
\n";
}
}
/**
* 输出所有类属性和SQL
*
* @param bool $format 使用哪种打印方式, false为 print_r, true为var_dump
* @return void
*/
function debug_sql_info(){
//基本信息
$mysql_err = $this->getError() == '' ? 'NULL' : $this->getError();
echo "DBCommon Debug info
\n";
echo "Execute SQL :". $this->getLastSql() ."
\n";
echo "MySQL Error :". $mysql_err ."
\n";
echo "SQL Runtime :". $this->getRunTime() ."
\n";
}
/**
* 调试函数
*
* @param bool $format 使用哪种打印方式, false为 print_r, true为var_dump
* @return void
*/
function debug($level = 1){
switch($level){
case 0: $this->debug_class_var(); $this->debug_class_method(); break;
case 1: $this->debug_sql_info(); break;
case 2: $this->debug_sql_info(); $this->debug_table_info(); break;
case 3: $this->debug_sql_info(); $this->debug_table_info(); $this->debug_server_info(); break;
default: $this->debug_sql_info();
}
}
/**
* 调试函数: 打印类属性
*
* @param void
* @return void
*/
function v(){
$this->debug_class_var();
}
/**
* 调试函数: 打印类方法
*
* @param void
* @return void
*/
function m(){
$this->debug_class_method();
}
//--------------------------------
//
// 兼容 TMService 的简洁接口
//
//--------------------------------
/**
* 查询结果:二维数组返回
*
* @param string $sql 需要执行的SQL
* @return 成功返回获取的二维数组,失败返回false, 数据空返回NULL
*/
function query($sql){
$optType = trim(strtolower(substr(ltrim($sql), 0, 6)));
if (in_array($optType, array('update', 'insert', 'delete'))){
return $this->execute($sql);
}
return $this->getAll($sql);
}
/**
* 插入数据
*
* @param array $field_array 字段数组(数组中的键相当于字段名,数组值相当于值, 类似 array( 'id' => 100, 'user' => 'heiyeluren')
* @param string $table 表名
* @return bool 执行成功返回true, 失败返回false
*/
function insert($arrField, $table){
return $this->autoExecute($table, $arrField, 1);
}
/**
* 更新数据
*
* @param array $field_array 字段数组(数组中的键相当于字段名,数组值相当于值, 类似 array( 'id' => 100, 'user' => 'heiyeluren')
* @param string $table 表名
* @param string $where 如果是更新操作,可以添加WHERE的条件
* @return bool 执行成功返回true, 失败返回false
*/
function update($arrField, $where, $table){
if (trim($where) == ''){
return false;
}
return $this->autoExecute($table, $arrField, 2, $where);
}
/**
* 获取某个表的Count
*
* @param array $arrField 需要处理的where条件的key,value
* @param string $table 需要获取的表名
* @return 成功返回获取的一个整数值,失败返回false, 数据空返回NULL
*/
function getCount($arrField, $notFields, $table){
$sql = "SELECT COUNT(1) as cnt FROM ".$table." WHERE ";
foreach ($arrField as $key => $value) {
$sql .= " `$key`='$value' AND ";
}
if (!emptyempty($notFields)) {
foreach ($arrField as $key => $value) {
$sql .= " `$key`!='$value' AND ";
}
}
$sql .= " 1 ";
$row = $this->getOne($sql);
if ($row===NULL || $row===false){
return $row;
}
if (is_array($row)){
return (int)current($row);
}
return (int)$row;
}
}
?>
$key = $value;
}
/**
* 读取类属性
*
* @param str $key需要读取的属性名
* @return void
*/
function get($key){
return $this->$key;
}
//------------------------
//
// 基础底层操作接口
//
//------------------------
/**
* 构造函数
*
* 传递配置信息,配置信息数组结构:
* $masterConf = array(
* "host" => Master数据库主机地址
* "user" => 登录用户名
* "pwd" => 登录密码
* "db" => 默认连接的数据库
* );
* $slaveConf = array(
* "host" => Slave1数据库主机地址|Slave2数据库主机地址|...
* "user" => 登录用户名
* "pwd" => 登录密码
* "db" => 默认连接的数据库
* );
*
* @param bool $singleHost是否只有一台主机
* @return void
*/
function DBCommon($masterConf, $slaveConf=array(), $singleHost = true){
//构造数据库配置信息
if (is_array($masterConf) && !empty($masterConf)){
$this->wdbConf = $masterConf;
}
if (!is_array($slaveConf) || empty($slaveConf)){
$this->rdbConf = $masterConf;
} else {
$this->rdbConf = $slaveConf;
}
$this->singleHost = $singleHost;
//初始化连接(一般不推荐)
if ($this->isInitConn){
$this->getDbWriteConn();
if (!$this->singleHost){
$this->getDbReadConn();
}
}
}
/**
* 获取Master的写数据连接
*/
function getDbWriteConn(){
//判断是否已经连接
if ($this->wdbConn && is_resource($this->wdbConn)) {
return $this->wdbConn;
}
//没有连接则自行处理
$db = $this->connect($this->wdbConf['host'], $this->wdbConf['user'], $this->wdbConf['pwd'], $this->wdbConf['db']);
if (!$db || !is_resource($db)) {
return false;
}
$this->wdbConn = $db;
return $this->wdbConn;
}
/**
* 获取Slave的读数据连接
*/
function getDbReadConn(){
//如果有可用的Slave连接,随机挑选一台Slave
if (is_array($this->rdbConn) && !empty($this->rdbConn)) {
$key = array_rand($this->rdbConn);
if (isset($this->rdbConn[$key]) && is_resource($this->rdbConn[$key])) {
return $this->rdbConn[$key];
}
}
//连接到所有Slave数据库,如果没有可用的Slave机则调用Master
$arrHost = explode("|", $this->rdbConf['host']);
if (!is_array($arrHost) || empty($arrHost)){
return $this->getDbWriteConn();
}
$this->rdbConn = array();
foreach($arrHost as $tmpHost){
$db = $this->connect($tmpHost, $this->rdbConf['user'], $this->rdbConf['pwd'], $this->rdbConf['db']);
if ($db && is_resource($db)){
$this->rdbConn[] = $db;
}
}
//如果没有一台可用的Slave则调用Master
if (!is_array($this->rdbConn) || empty($this->rdbConn)){
$this->errorLog("Not availability slave db connection, call master db connection");
return $this->getDbWriteConn();
}
//随机在已连接的Slave机中选择一台
$key = array_rand($this->rdbConn);
if (isset($this->rdbConn[$key])&& is_resource($this->rdbConn[$key])){
return $this->rdbConn[$key];
}
//如果选择的slave机器是无效的,并且可用的slave机器大于一台则循环遍历所有能用的slave机器
if (count($this->rdbConn) > 1){
foreach($this->rdbConn as $conn){
if (is_resource($conn)){
return $conn;
}
}
}
//如果没有可用的Slave连接,则继续使用Master连接
return $this->getDbWriteConn();
}
/**
* 连接到MySQL数据库公共方法
*/
function connect($dbHost, $dbUser, $dbPasswd, $dbDatabase){
//连接数据库主机
$db = mysql_connect($dbHost, $dbUser, $dbPasswd);
if (!$db) {
$this->errorLog("Mysql connect ". $dbHost ." failed");
return false;
}
//选定数据库
if (!mysql_select_db($dbDatabase, $db)) {
$this->errorLog("select db $dbDatabase failed", $db);
return false;
}
//设置字符集
if ($this->isCharset){
if ( $this->dbVersion == '' ){
$res = mysql_query("SELECT VERSION()");
$this->dbVersion = mysql_result($res, 0);
}
if ($this->dbCharset!='' && preg_match("/^(5.|4.1)/", $this->dbVersion)){
if (mysql_query("SET NAMES '".$this->dbCharset."'", $db) === false){
$this->errorLog("Set db_host '$dbHost' charset=". $this->dbCharset ." failed.", $db);
return false;
}
}
}
return $db;
}
/**
* 关闭数据库连接
*/
function disconnect($dbConn=null, $closeAll=false){
//关闭指定数据库连接
if ($dbConn && is_resource($dbConn)){
mysql_close($dbConn);
$dbConn = null;
}
//关闭所有数据库连接
if ($closeAll){
if ($this->rdbConn && is_resource($this->rdbConn)){
mysql_close($this->rdbConn);
$this->rdbConn = null;
}
if (is_array($this->rdbConn) && !empty($this->rdbConn)){
foreach($this->rdbConn as $conn){
if ($conn && is_resource($conn)){
mysql_close($conn);
}
}
$this->rdbConn = array();
}
}
return true;
}
/**
* 选择数据库
*/
function selectDb($dbName, $dbConn=null){
//重新选择一个连接的数据库
if ($dbConn && is_resource($dbConn)){
if (!mysql_select_db($dbName, $dbConn)){
$this->errorLog("Select database:$dbName failed.", $dbConn);
return false;
}
return true;
}
//重新选择所有连接的数据库
if ($this->wdbConn && is_resource($this->wdbConn)){
if (!mysql_select_db($dbName, $this->wdbConn)){
$this->errorLog("Select database:$dbName failed.", $this->wdbConn);
return false;
}
}
if (is_array($this->rdbConn && !empty($this->rdbConn))){
foreach($this->rdbConn as $conn){
if ($conn && is_resource($conn)){
if (!mysql_select_db($dbName, $conn)){
$this->errorLog("Select database:$dbName failed.", $conn);
return false;
}
}
}
}
return true;
}
/**
* 执行SQL语句(底层操作)
*/
function _query($sql, $isMaster=false){
if (trim($sql) == ""){
$this->errorLog("Sql query is empty.");
return false;
}
//是否只有一台数据库机器
if ($this->singleHost){
$isMaster = true;
}
//获取执行SQL的数据库连接
if (!$isMaster){
$optType = trim(strtolower(substr(ltrim($sql), 0, 6)));
}
if ($isMaster || $optType!="select"){
$dbConn = $this->getDbWriteConn();
} else {
$dbConn = $this->getDbReadConn();
}
if (!$dbConn || !is_resource($dbConn)){
$this->isError = true;
$this->errMsg= 'Not availability db connection.';
$this->currConn = null;
$this->errorLog("Not availability db connection. Query SQL:". $sql);
if ($this->isExit) {
exit;
}
return false;
}
//记录执行的SQL
if ($this->logSqlLevel){
$isLog = false;
$logLevel = $this->logSqlLevel;
if ($logLevel==1 && in_array($optType, array('insert'))){
$isLog = true;
}
if ($logLevel==2 && in_array($optType, array('insert', 'update'))){
$isLog = true;
}
if ($logLevel==3 && in_array($optType, array('insert', 'update', 'delete'))){
$isLog = true;
}
if ($logLevel==4 && in_array($optType, array('insert', 'update', 'delete', 'select'))){
$isLog = true;
}
if ($isLog){
$this->errorLog($sql);
}
}
//执行查询
$this->currConn = $dbConn;
$this->dbSql = $sql;
$this->dbResult = null;
if ($this->isRuntime){
$startTime = $this->getTime();
$this->dbResult = @mysql_query($sql, $dbConn);
$this->runTime = $this->getTime() - $startTime;
} else {
$this->dbResult = @mysql_query($sql, $dbConn);
}
if ($this->dbResult === false){
$this->isError = true;
$this->errMsg= 'MySQL errno:'. mysql_errno($dbConn) .', error:'. mysql_error($dbConn);
$this->errorLog("Query sql failed. SQL:".$sql, $dbConn);
if ($this->isExit) {
exit;
}
return false;
}
$this->isError = false;
$this->errMsg= '';
return true;
}
/**
* 错误日志
*/
function errorLog($msg='', $conn=null){
if (!$this->isLog){
return;
}
if ($msg=='' && !$conn) {
return false;
}
$log = "MySQL Error: $msg";
if ($conn && is_resource($conn)) {
$log .= " mysql_msg:". mysql_error($conn);
}
$log .= " [". date("Y-m-d H:i:s") ."]";
if ($this->logFile != ''){
error_log($log ."\n", 3, $this->logFile);
} else {
error_log($log);
}
return true;
}
//--------------------------
//
// 数据获取接口
//
//--------------------------
/**
* 获取SQL执行的全部结果集(二维数组)
*
* @param string $sql 需要执行查询的SQL语句
* @return 成功返回查询结果的二维数组,失败返回false, 数据空返回NULL
*/
function getAll($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
while ($row = @mysql_fetch_array($this->dbResult, $this->fetchMode)) {
$this->dbRecord[] = $row;
}
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || empty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取单行记录(一维数组)
*
* @param string $sql 需要执行查询的SQL语句
* @return 成功返回结果记录的一维数组,失败返回false, 数据空返回NULL
*/
function getRow($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
$this->dbRecord = @mysql_fetch_array($this->dbResult, $this->fetchMode);
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || empty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取一列数据(一维数组)
*
* @param string $sql 需要获取的字符串
* @param string $field 需要获取的列,如果不指定,默认是第一列
* @return 成功返回提取的结果记录的一维数组,失败返回false, 数据空返回NULL
*/
function getCol($sql, $field='', $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
while($row = @mysql_fetch_array($this->dbResult, $this->fetchMode)){
if (trim($field) == ''){
$this->dbRecord[] = current($row);
} else {
$this->dbRecord[] = $row[$field];
}
}
@mysql_free_result($this->dbResult);
if (!is_array($this->dbRecord) || empty($this->dbRecord)){
return NULL;
}
return $this->dbRecord;
}
/**
* 获取一个数据(当条数组)
*
* @param string $sql 需要执行查询的SQL
* @return 成功返回获取的一个数据,失败返回false, 数据空返回NULL
*/
function getOne($sql, $field='', $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
$this->dbRecord = array();
$row = @mysql_fetch_array($this->dbResult, $this->fetchMode);
@mysql_free_result($this->dbResult);
if (!is_array($row) || empty($row)){
return NULL;
}
if (trim($field) != ''){
$this->dbRecord = $row[$field];
}else{
$this->dbRecord = current($row);
}
return $this->dbRecord;
}
/**
* 获取指定各种条件的记录
*
* @param string $table 表名(访问的数据表)
* @param string $field 字段(要获取的字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $order 排序(按照什么字段排序,不包括ORDER BY,默认为空)
* @param string $limit 限制记录(需要提取多少记录,不包括LIMIT,默认为空)
* @param bool $single 是否只是取单条记录(是调用getRow还是getAll,默认是false,即调用getAll)
* @return 成功返回记录结果集的数组,失败返回false
*/
function getRecord($table, $field='*', $where='', $order='', $limit='', $single=false, $isMaster=false){
$sql = "SELECT $field FROM $table";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= trim($order)!='' ? " ORDER BY $order " : $order;
$sql .= trim($limit)!='' ? " LIMIT $limit " : $limit;
if ($single){
return $this->getRow($sql, $isMaster);
}
return $this->getAll($sql, $isMaster);
}
/**
* 获取指点各种条件的记录(跟getRecored类似)
*
* @param string $table 表名(访问的数据表)
* @param string $field 字段(要获取的字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param array $order_arr 排序数组(格式类似于: array('id'=>true), 那么就是按照ID为顺序排序, array('id'=>false), 就是按照ID逆序排序)
* @param array $limit_arr 提取数据的限制数组()
* @return unknown
*/
function getRecordByWhere($table, $field='*', $where='', $arrOrder=array(), $arrLimit=array(), $isMaster=false){
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
if (is_array($arrOrder) && !empty($arrOrder)){
$arrKey = key($arrOrder);
$sql .= " ORDER BY $arrKey " . ($arrOrder[$arrKey] ? "ASC" : "DESC");
}
if (is_array($arrLimit) && !empty($arrLimit)){
$startPos = intval(array_shift($arrLimit));
$offset = intval(array_shift($arrLimit));
$sql .= " LIMIT $startPos,$offset ";
}
return $this->getAll($sql, $isMaster);
}
/**
* 获取指定条数的记录
*
* @param string $table 表名
* @param int $startPos 开始记录
* @param int $offset 偏移量
* @param string $field 字段名
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $order 排序(按照什么字段排序,不包括ORDER BY,默认为空)
* @return 成功返回包含记录的二维数组,失败返回false
*/
function getRecordByLimit($table, $startPos, $offset, $field='*', $where='', $oder='', $isMaster=false){
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= trim($order)!='' ? " ORDER BY $order " : $order;
$sql .= " LIMIT $startPos,$offset ";
return $this->getAll($sql, $isMaster);
}
/**
* 获取排序记录
*
* @param string $table 表名
* @param string $orderField 需要排序的字段(比如id)
* @param string $orderMethod 排序的方式(1为顺序, 2为逆序, 默认是1)
* @param string $field 需要提取的字段(默认是*,就是所有字段)
* @param string $where 条件(获取记录的条件语句,不包括WHERE,默认为空)
* @param string $limit 限制记录(需要提取多少记录,不包括LIMIT,默认为空)
* @return 成功返回记录的二维数组,失败返回false
*/
function getRecordByOrder($table, $orderField, $orderMethod=1, $field='*', $where='', $limit='', $isMaster=false){
//$order_method的值为1则为顺序, $order_method值为2则2则是逆序排列
$sql = " SELECT $field FROM $table ";
$sql .= trim($where)!='' ? " WHERE $where " : $where;
$sql .= " ORDER BY $orderField " . ( $orderMethod==1 ? "ASC" : "DESC");
$sql .= trim($limit)!='' ? " LIMIT $limit " : $limit;
return $this->getAll($sql, $isMaster);
}
/**
* 分页查询(限制查询的记录条数)
*
* @param string $sql 需要查询的SQL语句
* @param int $startPos 开始记录的条数
* @param int $offset 每次的偏移量,需要获取多少条
* @return 成功返回获取结果记录的二维数组,失败返回false
*/
function limit_query($sql, $startPos, $offset, $isMaster=false){
$start_pos = intval($startPos);
$offset = intval($offset);
$sql = $sql . " LIMIT $startPos,$offset ";
return $this->getAll($sql, $isMaster);
}
//--------------------------
//
// 无数据返回操作接口
//
//--------------------------
/**
* 执行执行非Select查询操作
*
* @param string $sql 查询SQL语句
* @return bool成功执行返回true, 失败返回false
*/
function execute($sql, $isMaster=false){
if (!$this->_query($sql, $isMaster)){
return false;
}
return true;
/*$count = @mysql_affected_rows($this->dbLink);
if ($count100, 'user' => 'heiyeluren')
* @param int $mode 执行操作的模式 (是插入还是更新操作, 1是插入操作Insert, 2是更新操作Update)
* @param string $where 如果是更新操作,可以添加WHERE的条件
* @return bool 执行成功返回true, 失败返回false
*/
function autoExecute($table, $arrField, $mode, $where='', $isMaster=false){
if ($table=='' || !is_array($arrField) || empty($arrField)){
return false;
}
//$mode为1是插入操作(Insert), $mode为2是更新操作
if ($mode == 1){
$sql = " INSERT INTO `$table` SET ";
} elseif ($mode == 2) {
$sql = " UPDATE `$table` SET ";
} else {
$this->errorLog("Operate type '$mode' is error, in call DB::autoExecute process table $table.");
return false;
}
foreach ($arrField as $key => $value){
$sql .= "`$key`='$value',";
}
$sql = rtrim($sql, ',');
if ($mode==2 && $where!=''){
$sql .= "WHERE $where";
}
return $this->execute($sql, $isMaster);
}
/**
* 锁表表
*
* @param string $tblName 需要锁定表的名称
* @return mixed 成功返回执行结果,失败返回错误对象
*/
function lockTable($tblName){
return $this->_query("LOCK TABLES $tblName", true);
}
/**
* 对锁定表进行解锁
*
* @param string $tblName 需要锁定表的名称
* @return mixed 成功返回执行结果,失败返回错误对象
*/
function unlockTable($tblName){
return $this->_query("UNLOCK TABLES $tblName", true);
}
/**
* 设置自动提交模块的方式(针对InnoDB存储引擎)
* 一般如果是不需要使用事务模式,建议自动提交为1,这样能够提高InnoDB存储引擎的执行效率,如果是事务模式,那么就使用自动提交为0
*
* @param bool $autoCommit 如果是true则是自动提交,每次输入SQL之后都自动执行,缺省为false
* @return mixed 成功返回true,失败返回错误对象
*/
function setAutoCommit($autoCommit = false){
$autoCommit = ( $autoCommit ? 1 : 0 );
return $this->_query("SET AUTOCOMMIT = $autoCommit", true);
}
/**
* 开始一个事务过程(针对InnoDB引擎,兼容使用 BEGIN 和 START TRANSACTION)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function startTransaction(){
if (!$this->_query("BEGIN")){
return $this->_query("START TRANSACTION", true);
}
}
/**
* 提交一个事务(针对InnoDB存储引擎)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function commit(){
if (!$this->_query("COMMIT", true)){
return false;
}
return $this->setAutoCommit( true );
}
/**
* 发生错误,会滚一个事务(针对InnoDB存储引擎)
*
* @return mixed 成功返回true,失败返回错误对象
*/
function rollback(){
if (!$this->_query("ROLLBACK", true)){
return false;
}
return $this->setAutoCommit( true );
}
//--------------------------
//
// 其他数据操作接口
//
//--------------------------
/**
* 获取上次插入操作的的ID
*
* @return int 如果没有连接或者查询失败,返回0, 成功返回ID
*/
function getLastId(){
$dbConn = $this->getDbWriteConn();
if (($lastId = mysql_insert_id($dbConn)) > 0){
return $lastId;
}
return $this->getOne("SELECT LAST_INSERT_ID()", '', true);
}
/**
* 获取记录集里面的记录条数 (用于Select操作)
*
* @return int 如果上一次无结果集或者记录结果集为空,返回0, 否则返回结果集数量
*/
function getNumRows($res=null){
if (!$res || !is_resource($res)){
$res = $this->dbResult;
}
return mysql_num_rows($res);
}
/**
* 获取受到影响的记录数量 (用于Update/Delete/Insert操作)
*
* @return int 如果没有连接或者影响记录为空, 否则返回影响的行数量
*/
function getAffectedRows(){
$dbConn = $this->getDbWriteConn();
if ( ($affetedRows = mysql_affected_rows($dbConn)) getOne("SELECT ROW_COUNT()", "", true);
}
//--------------------------
//
// 相应配合操作接口
//
//--------------------------
/**
* 获取最后一次查询的SQL语句
*
* @return string 返回最后一次查询的SQL语句
*/
function getLastSql(){
return $this->dbSql;
}
/**
* 返回SQL最后操作的数据库记录结果集
*
* @return mixed 最后结果集,可能是数组或者普通单个元素值
*/
function getDBRecord(){
return $this->dbRecord;
}
/**
* 获取当前操作的数据库连接资源
*
* @return resouce 返回当前正在执行操作的数据库链接资源
*/
function getCurrConnection(){
return $this->currConn;
}
/**
* SQL 执行是否出错
*
* @return bool
*/
function isError(){
return $this->isError;
}
/**
* SQL 执行错误消息
*
* @return string
*/
function getError(){
return $this->errMsg;
}
/**
* 获取执行时间
*
* @return float
*/
function getRunTime(){
if ($this->isRuntime){
return sprintf("%.6f sec",$this->runTime);
}
return 'NULL';
}
/**
* 获取当前时间函数
*
* @param void
* @return float $time
*/
function getTime(){
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
//--------------------------
//
// 开发调试监控接口
//
//--------------------------
/**
* 调试信息内部输出接口
*
* @param string $title 需要输出的标题
* @param array $index 需要输出的内容数组(二维数组)
* @return void
*/
function _debug_print_table($title, $index, $content_pre = false){
echo "".$title."\n";
//二维数组
if (isset($index)){
echo "";
foreach($index as $k => $v){
echo "$k";
}
echo "";
foreach($index as $v){
echo "";
foreach($v as $_v){
$_v = $_v == NULL ? ' ' : $_v;
echo !$content_pre ? "$_v" : "$_v";
}
echo "";
}
echo "
";
}
//一维数组
else {
echo "";
foreach($index as $k => $v){
echo "$k";
}
echo "";
foreach($index as $k => $v){
$v = $v == NULL ? ' ' : $v;
echo !$content_pre ? "$v" : "$v";
}
echo "
";
}
}
/**
* 输出数据表结构信息
*
* @param void
* @return void
*/
function debug_table_info($table_name = ''){
$curr_sql = $this->getLastSql();
//SQL性能信息
echo "
";
$explain = $this->getAll("explain ".$curr_sql);
if (!empty($explain)){
$this->_debug_print_table('SQL Explain:', $explain);
}
//总体SQL详细操作性能信息
$version = $this->getOne("select version()");
if (preg_match("/^(5.)/", $version) && substr($version,0,6) >= '5.0.37'){
if ($this->execute("set profiling = 1")){
$this->execute($curr_sql);
$index = $this->getAll("show profile cpu,block io,memory,swaps for query 1");
$this->execute("set profiling = 0");
$this->_debug_print_table("SQL Performance Profiling:", $index);
$index = $this->getAll("show profiles");
$this->_debug_print_table("", $index);
}
}
//获取刚才操作的表名
$table_name = isset($explain) ? $explain['table'] : $explain['table'];
if ($table_name == ''){
return;
}
//索引列表
$index = $this->getAll("show index from $table_name");
$this->_debug_print_table("Table '$table_name' Index:", $index);
//表结构
$index = $this->getAll("desc $table_name");
$this->_debug_print_table("Table '$table_name' Fileds:", $index);
//创建表语句
$explain = $this->getRow("show create table $table_name");
if (!empty($explain)){
$this->_debug_print_table("Table '$table_name' Create:", $explain, true);
}
}
/**
* 输出数据库服务器运行信息
*
* @param void
* @return void
*/
function debug_server_info(){
echo "
";
//进程信息
$index = $this->getAll("show full processlist");
$this->_debug_print_table("Database Process List", $index);
//变量信息
$index = $this->getAll("show global variables");
$this->_debug_print_table("Database Variables List", $index);
//状态信息
$index = $this->getAll("show global status");
$this->_debug_print_table("Database Status Info", $index);
//服务器打开表信息
$index = $this->getAll("show open tables");
$this->_debug_print_table("Database Open tables List", $index);
}
/**
* 输出所有类属性和值
*
* @return void
*/
function debug_class_var(){
$class = get_class($this);
//其他类属性
echo "
$class Attribute: \n";
echo "
";
$vars = get_object_vars($this);
print_r($vars);
echo "\n
";
}
/**
* 输出所有类方法名
*
* @return void
*/
function debug_class_method() {
$class = get_class($this);
$arr = get_class_methods($class);
echo "$class method list
\n";
foreach ($arr as $method) {
echo "\t$method()
\n";
}
}
/**
* 输出所有类属性和SQL
*
* @param bool $format 使用哪种打印方式, false为 print_r, true为var_dump
* @return void
*/
function debug_sql_info(){
//基本信息
$mysql_err = $this->getError() == '' ? 'NULL' : $this->getError();
echo "DBCommon Debug info
\n";
echo "Execute SQL :". $this->getLastSql() ."
\n";
echo "MySQL Error :". $mysql_err ."
\n";
echo "SQL Runtime :". $this->getRunTime() ."
\n";
}
/**
* 调试函数
*
* @param bool $format 使用哪种打印方式, false为 print_r, true为var_dump
* @return void
*/
function debug($level = 1){
switch($level){
case 0: $this->debug_class_var(); $this->debug_class_method(); break;
case 1: $this->debug_sql_info(); break;
case 2: $this->debug_sql_info(); $this->debug_table_info(); break;
case 3: $this->debug_sql_info(); $this->debug_table_info(); $this->debug_server_info(); break;
default: $this->debug_sql_info();
}
}
/**
* 调试函数: 打印类属性
*
* @param void
* @return void
*/
function v(){
$this->debug_class_var();
}
/**
* 调试函数: 打印类方法
*
* @param void
* @return void
*/
function m(){
$this->debug_class_method();
}
//--------------------------------
//
// 兼容 TMService 的简洁接口
//
//--------------------------------
/**
* 查询结果:二维数组返回
*
* @param string $sql 需要执行的SQL
* @return 成功返回获取的二维数组,失败返回false, 数据空返回NULL
*/
function query($sql){
$optType = trim(strtolower(substr(ltrim($sql), 0, 6)));
if (in_array($optType, array('update', 'insert', 'delete'))){
return $this->execute($sql);
}
return $this->getAll($sql);
}
/**
* 插入数据
*
* @param array $field_array 字段数组(数组中的键相当于字段名,数组值相当于值, 类似 array( 'id' => 100, 'user' => 'heiyeluren')
* @param string $table 表名
* @return bool 执行成功返回true, 失败返回false
*/
function insert($arrField, $table){
return $this->autoExecute($table, $arrField, 1);
}
/**
* 更新数据
*
* @param array $field_array 字段数组(数组中的键相当于字段名,数组值相当于值, 类似 array( 'id' => 100, 'user' => 'heiyeluren')
* @param string $table 表名
* @param string $where 如果是更新操作,可以添加WHERE的条件
* @return bool 执行成功返回true, 失败返回false
*/
function update($arrField, $where, $table){
if (trim($where) == ''){
return false;
}
return $this->autoExecute($table, $arrField, 2, $where);
}
/**
* 获取某个表的Count
*
* @param array $arrField 需要处理的where条件的key,value
* @param string $table 需要获取的表名
* @return 成功返回获取的一个整数值,失败返回false, 数据空返回NULL
*/
function getCount($arrField, $notFields, $table){
$sql = "SELECT COUNT(1) as cnt FROM ".$table." WHERE ";
foreach ($arrField as $key => $value) {
$sql .= " `$key`='$value' AND ";
}
if (!empty($notFields)) {
foreach ($arrField as $key => $value) {
$sql .= " `$key`!='$value' AND ";
}
}
$sql .= " 1 ";
$row = $this->getOne($sql);
if ($row===NULL || $row===false){
return $row;
}
if (is_array($row)){
return (int)current($row);
}
return (int)$row;
}
}
?>
调用上面数据库操作对象:
view plaincopy to clipboardprint?
/**
* 工厂模式对象获取
*
*/
class common
{
/**
* 数据库单例对象
*/
public static $db = NULL;
/**
* 获取数据库对象
*
*
*
数据库使用示例和介绍:
$db = common::getDB();
//简洁接口
$db->query($sql);//查询,二维数组 (兼容TM)
$db->insert($arr, $table); //插入数据 (兼容TM)
$db->update($arr, $where, $table); //更新数据 (兼容TM)
$db->getCount($arr, $notfield, $table); //获取数量 (兼容TM)
//基本数据操作接口
$db->getAll($sql); //读取所有数据,二维数组
$db->getRow($sql); //读取一行记录,一维数组
$db->getCol($sql); //读取一列记录,一维数组
$db->getOne($sql); //获取单个单元值
$db->execute($sql); //纯执行SQL,返回true或false
$db->getNumRows(); //获取上一次select操作记录结果集总数
$db->getAffectedRows(); //获取上个操作影响的行数
//方便开发调试接口
$db->debug();//打印调试信息
$db->isError(); //SQL是否执行错误,true为有错误,false为没有错误
$db->getError(); //SQL执行错误消息
$db->getLastSql(); //获取最后一条执行的SQL
$db->getCurrConnection(); //获取当前数据库连接,方便直接自主操作MySQL
*/
public static function getDB(){
if (is_object(self::$db)){
return self::$db;
}
$cryption = new TMCryption();
$config = array(
"host"=> 'localhost',
"user"=> 'root',
"pwd" => '',
"db" => 'test',
);
self::$db = new DBCommon($config, array(), true);
self::$db->set('isCharset', false);
self::$db->query("SET NAMES utf8");
return self::$db;
}
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/37416/showart_2149408.html
页:
[1]