host = $aHost[0]; $this->port = isset( $aHost[1]) ? $aHost[1] : '3306';//默认端口3306 $this->user = $servers[1]; $this->password = $servers[2]; $this->dbname = $servers[3]; } /** * 检查并连接数据库 * @return mysqli */ public function connect(){ if ( isset(self::$mysqli[$this->host]) && !empty(self::$mysqli[$this->host]) && self::$mysqli[$this->host]->ping()) {//如果已经连接 return self::$mysqli[$this->host]; } if ( ! class_exists('mysqli')) { die('This Lib Requires The Mysqli Extention!'); } self::$mysqli[$this->host] = new mysqli($this->host, $this->user, $this->password, $this->dbname, $this->port); if ( $error = mysqli_connect_error()) { $backtrace = array(); $straces = debug_backtrace(); foreach ((array) $straces as $k => $v) { if ($k == 0) { continue; } $backtrace['backtrace'][$k]['file'] = $v['file']; $backtrace['backtrace'][$k]['line'] = $v['line']; $backtrace['backtrace'][$k]['function'] = $v['function']; $backtrace['backtrace'][$k]['args'] = $v['args']; } $errstr .= "backtrace:".var_export($backtrace, true); $this->errorlog( $error, "host:{$this->host},user:{$this->user},pwd:{$this->password},dbname:{$this->dbname},port:{$this->port},strace:{$errstr}"); } self::$mysqli[$this->host]->query("SET SQL_MODE=''"); // self::$mysqli[$this->host]->query("SET SQL_MODE='',CHARACTER_SET_CONNECTION='utf8',CHARACTER_SET_RESULTS='utf8',CHARACTER_SET_CLIENT='binary',NAMES 'utf8'"); return self::$mysqli[$this->host]; } /** * 执行sql * @param string $query public function query( $query){ $this->connect(); $result = self::$mysqli[$this->host]->query( $query); $error = mysqli_error( self::$mysqli[$this->host]); if ( $error) { $this->errorlog( $error, $query); } return $result; } */ public function query( $query , $showError = true, &$rows = 0){ $s = oo::getMsectime(); $this->connect(); $result = self::$mysqli[$this->host]->query( $query); $rows = self::$mysqli[$this->host]->affected_rows; $error = mysqli_error( self::$mysqli[$this->host]); if ( $error ) { $this->errorlog( $error, $query , $showError); } $e = oo::getMsectime(); if($e - $s > 2000){ //记录数据表查询日志,排查掉线问题 oo::logs()->debug3(['query' => $query, 'expend_ts'=>($e-$s)], 'db_query'); } return $result; } public function numRows($result=null){ //Return number of rows in selected table if( is_object( $result)){ return $result->num_rows; } return 0; } //查询一条记录 public function getOne($query, $mode = MYSQLI_ASSOC){ $result = $this->query($query); if ( ! is_object( $result)) { return array(); } $re = $result->fetch_array( $mode); if ( ! is_array($re)) { $re = array(); } return $re; } //查询多条记录 public function getAll($query, $mode = MYSQLI_ASSOC){ $result = $this->query($query); if ( ! is_object( $result)) { return array(); } $dataList = array(); while ($row = $result->fetch_array( $mode)) { $dataList[] = $row; } return $dataList; } /** * 缓存多行数据 */ public function getCacheAll($sql, $expire, $mode=MYSQLI_ASSOC, $key=false){ $key = $key===false ? md5($sql) : $key; if( ($temp = ocache::cache()->get($key)) === false){ $temp = $this->getAll($sql, $mode); ocache::cache()->set($key, $temp, $expire); } return $temp; } /** * 缓存一行数据 */ public function getCacheOne($sql, $expire, $mode=MYSQLI_ASSOC, $key=false){ $key = $key===false ? md5($sql) : $key; if( ($temp = ocache::cache()->get($key)) === false){ $temp = $this->getOne($sql, $mode); ocache::cache()->set($key, $temp, $expire); } return $temp; } public function fetchArray($result=null,$mode=MYSQLI_ASSOC){ if ( ! is_object($result)) { return array(); } $row = $result->fetch_array( $mode); return is_array($row) ? $row : array(); } public function fetchAssoc($result=null){ if ( ! is_object($result)) { return array(); } $row = $result->fetch_assoc(); return is_array($row) ? $row : array(); } //获取最新插入的记录ID public function insertID(){ return self::$mysqli[$this->host]->insert_id; } /** * * sql执行的影响行数 */ public function affectedRows(){ return self::$mysqli[$this->host]->affected_rows; } /** * * 关闭数据库 */ public function close(){ self::$mysqli[$this->host]->close(); unset(self::$mysqli[$this->host]); } /** * 安全性检测.调用escape存入的,一定要调unescape取出 */ public function escape( $string){ if ( oo::functions()->isPhpVersion()) { return addslashes( trim($string)); } return mysql_escape_string( trim($string)); } public function unescape( $string){ return stripslashes( $string); } /** * 事务处理章节 */ public function Start(){ $this->connect(); self::$mysqli[$this->host]->autocommit( false); } /** * * 提交事务 */ public function Commit(){ self::$mysqli[$this->host]->commit(); self::$mysqli[$this->host]->autocommit( true);//恢复自动提交 } public function CommitId(){ $aId = $this->getOne('SELECT LAST_INSERT_ID()', MYSQL_NUM); return (int)$aId[0]; } public function Rollback(){ self::$mysqli[$this->host]->rollback(); } /** * mysqli 预处理章节 */ /** * 该方法准备要执行的预处理语句 * @return mysqli_stmt */ public function stmtPrepare( $query){ if ( ! $query) { $this->errorlog('no query'); } $this->connect(); self::$stmt = self::$mysqli[$this->host]->prepare( $query); return self::$stmt; } /** * ping 用于保持php和mysql连接不超时 * 多用于死循环 */ public function ping() { if (self::$mysqli[$this->host]) { return self::$mysqli[$this->host]->ping(); } else { return false; } } /** * MYSQL报错日志 * @param string $msg */ private function errorlog( $msg='', $query='' ,$errorDie = true){ $date = date( 'Ymd'); $file = FCPATH . '/deBUG/mysql/' . $date . '.php'; $error = ''; if ( ! is_dir( FCPATH . '/deBUG/phperror')) { mkdir( FCPATH . '/deBUG/mysql', 0775); } if ( ! file_exists( $file)) { touch($file) && chmod($file, ENVIRONMENT == 'production' ? 0664 : 0666); $error = "escape( $query); $error .= date('Y-m-d H:i:s') . "-- ". mysqli_errno( self::$mysqli[$this->host]) . "-- msg:". $msg . ";" . " query:". $query; $backtrace = array(); $straces = debug_backtrace(); foreach ((array) $straces as $k => $v) { if ($k == 0) { continue; } $backtrace['backtrace'][$k]['file'] = $v['file']; $backtrace['backtrace'][$k]['line'] = $v['line']; $backtrace['backtrace'][$k]['function'] = $v['function']; $backtrace['backtrace'][$k]['args'] = $v['args']; } $error .= "backtrace:".var_export($backtrace, true); if ( ! ENVIRONMENT == 'production') { echo $error; } @file_put_contents( $file, $error . " \n ", FILE_APPEND | LOCK_EX); // oo::funModel('logs')->debug($error, 'mysql'.$date); // if($errorDie) // die(date('Y-m-d H:i:s').'-DB Insvalid!!!'); } }