<?php /** * Mysql数据库操作类 v2.0 * 2009.1.22 by Aboc QQ:9986584 * 增加文件缓存 * */ class DbMysql { /** * 在数据库操作中,只对数据库操作有影响的字符做转义 * 当此类正常后,所有数据操作 @ */ /* * 数据库连接句柄 */ private $_Db = NULL; /* * 是否持续连接 0.1 */ private $_pconnect = 0; /* * 编码 */ private $_charset = 'gbk'; /* *最后一次插入的ID */ private $_lastId = 0; /* * 默认数据库配置 */ private $_config = array ('dbhost' => 'localhost', 'dbuser' => 'root', 'dbpass' => 'root', 'dbname' => 'test'); /** * 缓存路径 */ private $_cachePath = ''; /** * sql语句 * * @var unknown_type */ private $_sql = ''; /** * 初始连接数据库 */ function __construct($config,$pconnect=0,$cachepath='cache') { if (empty($config)) $config = array(); $this->checkConfig ( $config ); $this->_pconnect = $pconnect; $this->connect (); $this->query ( 'set names ' . $this->_charset ); //设置编码 $this->_cachePath = $cachepath; } /** * 判断config变量 * * @param unknown_type $config */ private function checkConfig($config) { foreach ( $config as $key => $value ) { $this->_config [$key] = empty ( $value ) ? $this->_config [$key] : $value; } //return $this->_config; } /* * 连接数据库 */ private function connect() { // print_r($this->_config); if ($this->_pconnect) { $this->_Db = mysql_pconnect ( $this->_config ['dbhost'], $this->_config ['dbuser'], $this->_config ['dbpass'] ) or die ( '数据库连接失败' . mysql_errno () ); } else { $this->_Db = mysql_connect ( $this->_config ['dbhost'], $this->_config ['dbuser'], $this->_config ['dbpass'] ) or die ( '数据库连接失败' . mysql_errno () ); } if ($this->_Db != NULL) { mysql_select_db ( $this->_config ['dbname'], $this->_Db ) or die ( '数据库' . $this->_config ['dbname'] . '不存在' ); } } /** * 将变量的单引号或双引号转义 * * @param unknown_type $string */ private function strtag($string1) { if (is_array ( $string1 )) { foreach ( $string1 as $key => $value ) { $stringnew [$this->strtag ( $key )] = $this->strtag ( $value ); } } else { //在此做转义,对单引号 //TODO 好像 %也要转义吧? //$string = iconv("gbk","gbk",$string); $stringnew = mysql_real_escape_string ( $string1 ); // $stringnew = get_magic_quotes_gpc()?$string:addslashes ( $string1 ); // $stringnew=str_replace(array("'",'"'),array("\'",'\"'),$string1); } return $stringnew; } /** * 将数组转化为SQL接受的条件样式 * * @param unknown_type $array */ private function chageArray($array) { //MYSQL支持insert into joincart set session_id = 'dddd',product_id='44',number='7',jointime='456465' //所以更新和插入可以使用同一组数据 $array = $this->strtag ( $array ); //转义 $str = ''; foreach ( $array as $key => $value ) { $str .= empty ( $str ) ? "`" . $key . "`='" . $value."'" : ", `" . $key . "`='" . $value."'"; } return $str; } /** * 执行查询语句 * @return bool */ public function query($sql) { //echo $sql.'<br>'; $this->_sql = $sql; if (! $result = mysql_query ( $sql, $this->_Db)) { if(UC_DBUSER == 'root'){ echo $sql.'<br>'.mysql_error().'<br>'; //$this->createErrorLog($sql); die ( '数据库出错' ); } else { $subject = date("Y-m-d H:i:s")."数据库查询出错"; $thisurl = str::getThisUrl(); $error = mysql_error(); $content = <<<EOT 数据库查询出错,详细如下:<br /> $thisurl <br /> $error <br /> $sql EOT; $username = '风子'; if (function_exists('sendMail')){ sendMail('9986584@qq.com',$username,$subject,$content); die(':( 数据库查询出错,已经通知管理员,请稍后重试'); } } } else { return $result; } } /** * 插入记录 * */ public function insert($table, $array) { if(!is_array($array))return false; $array = $this->strtag ( $array ); //转义 $str = ''; $val = ''; foreach ($array as $key=>$value){ $str .= ($str != '')?",`$key`":"`$key`"; $val .= ($val != '')?",'$value'":"'$value'"; } $sql = 'insert into `' . $table . '` ('.$str. ') values('.$val.')'; //echo $sql;exit; if ($this->query ( $sql )) { $this->lastId(); return $this->_lastId?$this->_lastId:true; } else { return false; } } /** * 替换并插入 * @param unknown_type $table * @param unknown_type $array */ public function replaceInsert($table, $array) { if(!is_array($array))return false; $array = $this->strtag ( $array ); //转义 $str = ''; $val = ''; foreach ($array as $key=>$value){ $str .= ($str != '')?",`$key`":"`$key`"; $val .= ($val != '')?",'$value'":"'$value'"; } $sql = 'replace into `' . $table . '` ('.$str. ') values('.$val.')'; if ($this->query ( $sql )) { $this->lastId(); return $this->_lastId?$this->_lastId:true; } else { return false; } } /** * 批量插入记录 * * @param $table 表名 * @param $batchArray 批量数据 ,二维数组,健名必需相同,否则不能插入 */ public function insertBatch($table,$batchArray){ if(!is_array($batchArray))return false; $str = ''; $val = ''; $vals = array(); foreach ($batchArray as $keys=>$row){ if(!is_array($row))return false; foreach ($row as $key=>$value){ if($keys == 0)$str .= ($str != '')?",`$key`":"`$key`"; $val .= ($val != '')?",'$value'":"'$value'"; } $vals[$keys] = '('.$val.')'; $val = ''; } $vals = implode(',',$vals); $sql = 'insert into `' . $table . '` ('.$str. ') values '.$vals; if ($this->query ( $sql )) { $this->lastId(); return $this->_lastId?$this->_lastId:true; } else { return false; } } /** * 更新记录 * */ public function update($table, $array, $where = NULL) { if ($where == NULL) { $sql = 'update `' . $table . '` set ' . $this->chageArray ( $array ); } else { $sql = 'update `' . $table . '` set ' . $this->chageArray ( $array ) . ' where ' . $where; } if ($res = $this->query ( $sql )) { return $res; } else { return false; } } /** * 删除记录 * */ public function delete($table, $where = NULL) { if ($where == NULL) { $sql = 'delete from `' . $table . '`'; } else { $sql = 'delete from `' . $table . '` where ' . $where; } if ($this->query ( $sql )) { return true; } else { return false; } } /** * 获取一条记录 * */ public function fetchRow($sql,$cacheTime=0,$cacheId='') { if($content = $this->checkCache($sql,$cacheTime,$cacheId)){ return $content; } else{ $reult = $this->query ( $sql ); $row = mysql_fetch_assoc ( $reult ); if(!empty($row)){ foreach ($row as $key=>$value){ $row[$key] = stripslashes($value); } } if($cacheTime)$this->createCache($sql,$row,$cacheId); return $row; } } /** * 获取所有记录/用的mysql_fetch_assoc循环 * */ public function fetchAll($sql,$cacheTime=0,$cacheId='') { if($content = $this->checkCache($sql,$cacheTime,$cacheId)){ return $content; } else{ $result = $this->query ( $sql ); if ($result !== false) { $arr = array (); while ( $row = mysql_fetch_assoc ( $result ) ) { if(!empty($row)){ foreach ($row as $key=>$value){ $row[$key] = stripslashes($value); } } $arr [] = $row; } if($cacheTime)$this->createCache($sql,$arr,$cacheId); return $arr; } else { return array(); } } } /** * 获取最后一次影响的Id * */ public function lastId() { $this->_lastId = mysql_insert_id ( $this->_Db ); return $this->_lastId; } /** * 获取符合条件的记录数 * */ public function fetchNum($sql) { $reult = $this->query ( $sql ); $num = mysql_num_rows ( $reult ); return $num; } /** * 输出适合的where语句 */ public function quoteInto($string,$value ) { $value = $this->strtag($value); if(is_numeric($value)){ $string = str_replace('?',$value,$string); }else{ $string = str_replace('?',"'".$value."'",$string); } return $string; } /** * 数据数据库所用大小 * * @param unknown_type $dbname * @return unknown */ public function getSqlSize($dbname){ $sql = "SHOW TABLE STATUS from $dbname"; $rows = $this->fetchAll($sql); $total = 0; foreach ($rows as $row){ $total += $row['Data_length']; $total += $row['Index_length']; } return round($total/(1024*1024),2); } /** * 判断缓存文件是否有效,如果有效,则返回缓存内容 */ private function checkCache($sql,$cacheTime = 0,$cacheId=''){ //不缓存,直接返回 return false; if($cacheTime == 0){ return false; } else { $tmp = $this->createFilename($sql,$cacheId); if(file_exists($tmp['path'].$tmp['filename'])&&(filemtime($tmp['path'].$tmp['filename'])+$cacheTime)>time()){ $content = file_get_contents($tmp['path'].$tmp['filename']); return !empty($content)?unserialize($content):array(); } else{ return false; } } } /** * 生成缓存 */ private function createCache($sql,$data,$cacheId=''){ return; $tmp = $this->createFilename($sql,$cacheId); if(!is_dir($tmp['path']))@mkdir($tmp['path'],0777,true); @file_put_contents($tmp['path'].$tmp['filename'],serialize($data)); } /** * 根据sql语句生成文件名及路径 */ private function createFilename($sql,$cacheId=''){ if(!empty($cacheId))$sql = $cacheId; $data = array( 'path' => $this->_cachePath.'sql/', 'filename'=> '' ); if(empty($sql)) return $data; $tmpName = md5($sql); $data = array( 'path' => $this->_cachePath.'sql/'.substr($tmpName,0,2).'/'.substr($tmpName,2,2).'/', 'filename'=> substr($tmpName,3).'.tmp' ); return $data; } /** * 清除缓存 * * 条件为空则清除所有缓存 * * @return DbMysql */ public function clearCache($sql='',$cacheId=''){ $data = $this->createFilename($sql,$cacheId); $times = time(); if(!empty($sql) || !empty($cacheId)){ if(!empty($data['filename'])){ $path1= $data['path'].$data['filename']; if(file_exists($path1) && filemtime($path1)<$times)@unlink($path1); } } //清除所有缓存 else{ $this->clearFile($this->_cachePath,$times); } return true; } /** * 遍历删除文件及目录 */ private function clearFile($cachePath,$times){ $list = scandir($cachePath); foreach ($list as $key1=>$row1){ if($key1<=1)continue; $path1 = $cachePath.'/'.$row1; if(is_dir($path1)){ $this->clearFile($path1,$times); //rmdir($path1); } else { if(file_exists($path1) && filemtime($path1)<$times)@unlink($path1); } } } /** * 写错误日志 * * @param unknown_type $log */ private function createErrorLog($sql){ $log = array( date("Y-m-d H:i:s"), str::getThisUrl(), $sql, mysql_error () ); $log = implode(' - ',$log)."\r\n"; $filename = $this->_cachePath.'error/'.date("Y-m").'.txt'; if(!$fp = fopen($filename,'a+')){ echo '错误日志打开失败,请联络QQ:9986584'; } if( fwrite($fp,$log) === FALSE ){ echo '错误日志写入失败,请联络QQ:9986584'; } fclose($fp); } /** * 获取最后一次执行的sql语句 * */ public function getLastSql(){ return $this->_sql; } /** * 获取数据库中所有的表 * @param type $dbname * @return type */ function fetchAllTable($dbname=''){ $dbname = !empty($dbname)?$dbname:$this->_config['dbname']; $list = array(); $result = mysql_list_tables($dbname); if($result){ while ($row = mysql_fetch_row($result)){ $list[] = $row[0]; } return $list; } else return array(); } /** * 获取最后一次影响的记录数 * @return type */ function fetchChangeRow(){ return mysql_affected_rows(); } /** * 释放查询结果 */ private function free() { mysql_free_result($this->_Db); } /** * */ function __destruct() { // $this->free(); } } ?>