仿ZF功能的Mysql数据库操作类
2012-1-30 17:17 Monday  

分类: PHP 评论(38) 浏览(24612)

<?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(':(&nbsp;数据库查询出错,已经通知管理员,请稍后重试');
                 }
            }
        } 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();
    }
}

?>

+1 18

留下你的看法: