self::reconnect_time) && defined('MOBILE_SERVER') && self::$connect_time > 0) {
self::closeLink();
}
if (C('db.master') == C('db.slave'))
{
if (is_object(self::$link['slave'])){
self::$link['master'] = & self::$link['slave'];
return ;
}elseif (is_object(self::$link['master'])){
self::$link['slave'] = & self::$link['master'];
return ;
}
}
if (!in_array($host,array('master','slave'))) $host = 'slave';
$conf = C('db.'.$host);
if (is_object(self::$link[$host])) {
return;
}
self::$link[$host] = @new mysqli($conf['dbhost'], $conf['dbuser'], $conf['dbpwd'], $conf['dbname'], $conf['dbport']);
self::$connect_time = time();
if (mysqli_connect_errno()) throw_exception("Db Error: database connect failed");
switch (strtoupper($conf['dbcharset']))
{
case 'UTF-8':
$query_string = "
SET CHARACTER_SET_CLIENT = utf8,
CHARACTER_SET_CONNECTION = utf8,
CHARACTER_SET_DATABASE = utf8,
CHARACTER_SET_RESULTS = utf8,
CHARACTER_SET_SERVER = utf8,
COLLATION_CONNECTION = utf8_general_ci,
COLLATION_DATABASE = utf8_general_ci,
COLLATION_SERVER = utf8_general_ci,
sql_mode=''";
break;
case 'GBK':
$query_string = "
SET CHARACTER_SET_CLIENT = gbk,
CHARACTER_SET_CONNECTION = gbk,
CHARACTER_SET_DATABASE = gbk,
CHARACTER_SET_RESULTS = gbk,
CHARACTER_SET_SERVER = gbk,
COLLATION_CONNECTION = gbk_chinese_ci,
COLLATION_DATABASE = gbk_chinese_ci,
COLLATION_SERVER = gbk_chinese_ci,
sql_mode=''";
break;
default:
$error = "Db Error: charset is Invalid";
throw_exception($error);
}
//进行编码声明
if (!self::$link[$host]->query($query_string)) {
throw_exception("Db Error: ".mysqli_error(self::$link[$host]));
}
}
private static function closeLink()
{
foreach(self::$link as $key => $db){
if(is_object($db)){
mysqli_close($db);
}
unset(self::$link[$key]);
}
}
public static function ping($host = 'master') {
if (is_object(self::$link[$host])) {
// if (is_object(self::$link[$host]) && !self::$link[$host]->ping()) {
self::$link[$host]->close();
self::$link[$host] = null;
}
}
/**
* 执行查询
*
* @param string $sql
* @return mixed
*/
public static function query($sql, $host = 'master')
{
self::connect($host);
$staer = new statistic_tm();
$query = self::$link[$host]->query($sql);
$staer->end();
if ($query === false)
{
$error = 'Db Error: '.mysqli_error(self::$link[$host]);
if (C('debug')) {
throw_exception($error.'
'.$sql);
} else {
Log::record($error."\r\n".$sql,Log::ERR);
Log::record($sql,Log::SQL);
return false;
}
}
else
{
Log::record($sql . " [ RunTime:" . $staer->elapsed(6) . "s ]", Log::SQL);
return $query;
}
}
/**
* 取得数组
*
* @param string $sql
* @return bool/null/array
*/
public static function getAll($sql, $host = 'slave'){
self::connect($host);
$result = self::query($sql, $host);
if ($result === false) return array();
$array = array();
while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
$array[] = $tmp;
}
return !empty($array) ? $array : null;
}
/**
* SELECT查询
*
* @param array $param 参数
* @param object $obj_page 分类对象
* @return array
*/
public static function select($param, $obj_page='', $host = 'slave'){
self::connect($host);
static $_cache = array();
if (empty($param)) throw_exception('Db Error: select param is empty!');
if (empty($param['field'])){
$param['field'] = '*';
}
if (empty($param['count'])){
$param['count'] = 'count(*)';
}
if (isset($param['index'])){
$param['index'] = 'USE INDEX ('.$param['index'].')';
}
if (trim($param['where']) != ''){
if (strtoupper(substr(trim($param['where']),0,5)) != 'WHERE'){
if (strtoupper(substr(trim($param['where']),0,3)) == 'AND'){
$param['where'] = substr(trim($param['where']),3);
}
$param['where'] = 'WHERE '.$param['where'];
}
}else {
$param['where'] = '';
}
$param['where_group'] = '';
if (!empty($param['group'])){
$param['where_group'] .= ' group by '.$param['group'];
}
$param['where_order'] = '';
if (!empty($param['order'])){
$param['where_order'] .= ' order by '.$param['order'];
}
//判断是否是联表
$tmp_table = explode(',',$param['table']);
if (!empty($tmp_table) && count($tmp_table) > 1){
//判断join表数量和join条件是否一致
if ((count($tmp_table)-1) != count($param['join_on'])){
throw_exception('Db Error: join number is wrong!');
}
//trim 掉空白字符
foreach($tmp_table as $key=>$val){
$tmp_table[$key] = trim($val) ;
}
//拼join on 语句
for ($i=1;$isetTotalNum($count_fetch['count']);
$param['limit'] = $obj_page->getLimitStart().",".$obj_page->getEachNum();
}
if ($param['limit'] != ''){
$sql .= ' limit '.$param['limit'];
}
if ($param['cache'] !== false){
$key = is_string($param['cache_key'])?$param['cache_key']:md5($sql);
if (isset($_cache[$key])) return $_cache[$key];
}
$result = self::query($sql,$host);
if ($result === false) $result = array();
while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
$array[] = $tmp;
}
if ($param['cache'] !== false && !isset($_cache[$key])){
$_cache[$key] = $array;
}
return $array;
}
/**
* 插入操作
*
* @param string $table_name 表名
* @param array $insert_array 待插入数据
* @return mixed
*/
public static function insert($table_name, $insert_array=array(), $host = 'master'){
self::connect($host);
if (!is_array($insert_array)) return false;
$fields = array();
$value = array();
foreach ($insert_array as $key => $val){
$fields[] = self::parseKey($key);
$value[] = self::parseValue($val);
}
$sql = 'INSERT INTO `'.DBPRE.$table_name.'` ('.implode(',',$fields).') VALUES('.implode(',',$value).')';
//当数据库没有自增ID的情况下,返回 是否成功
$result = self::query($sql, $host);
$insert_id = self::getLastId($host);
return $insert_id ? $insert_id : $result;
}
/**
* 批量插入
*
* @param string $table_name 表名
* @param array $insert_array 待插入数据
* @return mixed
*/
public static function insertAll($table_name, $insert_array=array(), $host = 'master'){
self::connect($host);
if (!is_array($insert_array[0])) return false;
$fields = array_keys($insert_array[0]);
array_walk($fields,array(self,'parseKey'));
$values = array();
foreach ($insert_array as $data) {
$value = array();
foreach ($data as $key=>$val) {
$val = self::parseValue($val);
if (is_scalar($val)){
$value[] = $val;
}
}
$values[] = '('.implode(',',$value).')';
}
$sql = 'INSERT INTO `'.DBPRE.$table_name.'` ('.implode(',',$fields).') VALUES '.implode(',',$values);
$result = self::query($sql,$host);
$insert_id = self::getLastId($host);
return $insert_id ? $insert_id : $result;
}
/**
* 更新操作
*
* @param string $table_name 表名
* @param array $update_array 待更新数据
* @param string $where 执行条件
* @return bool
*/
public static function update($table_name, $update_array = array(), $where = '', $host = 'master'){
self::connect($host);
if (!is_array($update_array)) return false;
$string_value = '';
foreach ($update_array as $k => $v){
if (is_array($v)){
switch ($v['sign']){
case 'increase': $string_value .= " $k = $k + ". $v['value'] .","; break;
case 'decrease': $string_value .= " $k = $k - ". $v['value'] .","; break;
case 'calc': $string_value .= " $k = ". $v['value'] .","; break;
default: $string_value .= " $k = ". self::parseValue($v['value']) .",";
}
}else {
$string_value .= " $k = ". self::parseValue($v) .",";
}
}
$string_value = trim(trim($string_value),',');
if (trim($where) != ''){
if (strtoupper(substr(trim($where),0,5)) != 'WHERE'){
if (strtoupper(substr(trim($where),0,3)) == 'AND'){
$where = substr(trim($where),3);
}
$where = ' WHERE '.$where;
}
}
$sql = 'UPDATE `'.DBPRE.$table_name.'` AS `'.$table_name.'` SET '.$string_value.' '.$where;
$result = self::query($sql, $host);
return $result;
}
/**
* 删除操作
*
* @param string $table_name 表名
* @param string $where 执行条件
* @return bool
*/
public static function delete($table_name, $where = '', $host = 'master'){
self::connect($host);
if (trim($where) != ''){
if (strtoupper(substr(trim($where),0,5)) != 'WHERE'){
if (strtoupper(substr(trim($where),0,3)) == 'AND'){
$where = substr(trim($where),3);
}
$where = ' WHERE '.$where;
}
$sql = 'DELETE FROM `'.DBPRE.$table_name.'` '.$where;
return self::query($sql, $host);
}else {
throw_exception('Db Error: the condition of delete is empty!');
}
}
/**
* 取得上一步插入产生的ID
*
* @return int
*/
public static function getLastId($host = 'master'){
self::connect($host);
$id = mysqli_insert_id(self::$link[$host]);
if (!$id){
$result = self::query('SELECT last_insert_id() as id',$host);
if ($result === false) return false;
$id = mysqli_fetch_array($result,MYSQLI_ASSOC);
$id = $id['id'];
}
return $id;
}
/**
* 取得一行信息
*
* @param array $param
* @param string $fields
* @return array
*/
public static function getRow($param, $fields = '*', $host = 'slave'){
self::connect($host);
$table = $param['table'];
$wfield = $param['field'];
$value = $param['value'];
if (is_array($wfield)){
$where = array();
foreach ($wfield as $k => $v){
$where[] = $v."='".$value[$k]."'";
}
$where = implode(' and ',$where);
}else {
$where = $wfield."='".$value."'";
}
$sql = "SELECT ".$fields." FROM `".DBPRE.$table."` WHERE ".$where;
$result = self::query($sql,$host);
if ($result === false) return array();
return mysqli_fetch_array($result,MYSQLI_ASSOC);
}
/**
* 执行REPLACE操作
*
* @param string $table_name 表名
* @param array $replace_array 待更新的数据
* @return bool
*/
public static function replace($table_name, $replace_array = array(), $host = 'master'){
self::connect($host);
if (!empty($replace_array)){
foreach ($replace_array as $k => $v){
$string_field .= " $k ,";
$string_value .= " '". $v ."',";
}
$sql = 'REPLACE INTO `'.DBPRE.$table_name.'` ('.trim($string_field,', ').') VALUES('.trim($string_value,', ').')';
return self::query($sql,$host);
}else {
return false;
}
}
/**
* 返回单表查询记录数量
*
* @param string $table 表名
* @param $condition mixed 查询条件,可以为空,也可以为数组或字符串
* @return int
*/
public static function getCount($table, $condition = null, $host = 'slave'){
self::connect($host);
if (!empty($condition) && is_array($condition)){
$where = '';
foreach ($condition as $key=>$val) {
self::parseKey($key);
$val = self::parseValue($val);
$where .= ' AND '.$key.'='.$val;
}
$where = ' WHERE '.substr($where,4);
}elseif(is_string($condition)){
if (strtoupper(substr(trim($condition),0,3)) == 'AND'){
$where = ' WHERE '.substr(trim($condition),4);
}else{
$where = ' WHERE '.$condition;
}
}
$sql = 'SELECT COUNT(*) as `count` FROM `'.DBPRE.$table.'` as `'.$table.'` '.(isset($where) ? $where : '');
$result = self::query($sql,$host);
if ($result === false) return 0;
$result = mysqli_fetch_array($result,MYSQLI_ASSOC);
return $result['count'];
}
/**
* 执行SQL语句
*
* @param string $sql 待执行的SQL
* @return
*/
public static function execute($sql, $host = 'master'){
self::connect($host);
$result = self::query($sql,$host);
return $result;
}
/**
* 列出所有表
*
* @return array
*/
public static function showTables($host = 'slave'){
self::connect($host);
$sql = 'SHOW TABLES';
$result = self::query($sql,$host);
if ($result === false) return array();
$array = array();
while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
$array[] = $tmp;
}
return $array;
}
/**
* 显示建表语句
*
* @param string $table
* @return string
*/
public static function showCreateTable($table, $host = 'slave'){
self::connect($host);
$sql = 'SHOW CREATE TABLE `'.DBPRE.$table.'`';
$result = self::query($sql,$host);
if ($result === false) return '';
$result = mysqli_fetch_array($result,MYSQLI_ASSOC);
return $result['Create Table'];
}
/**
* 显示表结构信息
*
* @param string $table
* @return array
*/
public static function showColumns($table, $host = 'slave'){
self::connect($host);
$sql = 'SHOW COLUMNS FROM `'.DBPRE.$table.'`';
$result = self::query($sql,$host);
if ($result === false) return array();
$array = array();
while ($tmp=mysqli_fetch_array($result,MYSQLI_ASSOC)){
$array[$tmp['Field']] = array(
'name' => $tmp['Field'],
'type' => $tmp['Type'],
'null' => $tmp['Null'],
'default' => $tmp['Default'],
'primary' => (strtolower($tmp['Key']) == 'pri'),
'autoinc' => (strtolower($tmp['Extra']) == 'auto_increment'),
);
}
return $array;
}
/**
* 取得服务器信息
*
* @return string
*/
public static function getServerInfo($host = 'slave'){
self::connect($host);
$result = mysqli_get_server_info(self::$link[$host]);
return $result;
}
/**
* 格式化字段
*
* @param string $key 字段名
* @return string
*/
public static function parseKey(&$key){
$key = trim($key);
if(!preg_match('/[,\'\"\*\(\)`.\s]/',$key)) {
$key = '`'.$key.'`';
}
return $key;
}
/**
* 格式化值
*
* @param mixed $value
* @return mixed
*/
public static function parseValue($value){
$value = addslashes(stripslashes($value));//重新加斜线,防止从数据库直接读取出错
return "'".$value."'";
}
public static function beginTransaction($host = 'master'){
self::connect($host);
if (self::$iftransacte){
self::$link[$host]->autocommit(false);//关闭自动提交
}
self::$iftransacte = false;
}
public static function commit($host = 'master'){
if (!self::$iftransacte){
$result = self::$link[$host]->commit();
self::$link[$host]->autocommit(true);//开启自动提交
self::$iftransacte = true;
if (!$result) throw_exception("Db Error: ".mysqli_error(self::$link[$host]));
}
}
public static function rollback($host = 'master'){
if (!self::$iftransacte){
$result = self::$link[$host]->rollback();
self::$link[$host]->autocommit(true);
self::$iftransacte = true;
if (!$result) throw_exception("Db Error: ".mysqli_error(self::$link[$host]));
}
}
}