php实例分享之mysql数据备份


Posted in PHP onMay 19, 2014

备份:表结构和数据完全分开,默认有一个文件会记录所有表的结构,然后表中数据的备份 如果超过分卷的大小则会分成多个文件,不然则一个文件,参考了别人的代码,不过写的嘛,差强 人意,以后慢慢改吧。。。

代码如下:

<?php
/*
 * Created on 2014
 * Link for 527891885@qq.com
 * This is seocheck backup class
 */
class DbBackUp {
    private $conn;
    private $dbName;
    private $host;
    private $tag = '_b';
    //构造方法 链接数据库
    public function __construct($host='localhost', $dbUser='root', $dbPwd='', $dbName="seocheck", $charset='utf8') {
        @ob_start();
        @set_time_limit(0);
        $this->conn = mysql_connect($host, $dbUser, $dbPwd, true);
        if(!$this->conn) die("数据库系统连接失败!");
        mysql_query("set names ".$charset, $this->conn);
        mysql_select_db($dbName, $this->conn) or die("数据库连接失败!");
        $this->host = $host;
        $this->dbName = $dbName;
    }
    //获取数据库所有表名
    public function getTableNames () {
        $tables = array();
        $result = mysql_list_tables($this->dbName, $this->conn);
        if(!$result) die('MySQL Error: ' . mysql_error());
        while($row = mysql_fetch_row($result)) {
            $tables[] = $row[0];
        }
        return $tables;
    }
    //获取数据库表的字段信息
    public function getFieldsByTable ($table) {
        $fields = array();
        $str = '';
        $res = mysql_query("SHOW CREATE TABLE `{$table}`", $this->conn);
        if(!$res) die('MySQL Error: ' . mysql_error());
        while($rows = mysql_fetch_assoc($res)) {
            $str = str_replace("CREATE TABLE `{$table}` (", "", $rows['Create Table']);//DROP TABLE IF EXISTS `{$table}`\n
            $str = "--\n-- Table structure for table `{$table}`\n--\n\nCREATE TABLE IF NOT EXISTS `{$table}` ( ".$str;
            $str = str_replace(",", ", ", $str);
            $str = str_replace("`) ) ENGINE=InnoDB ", "`)\n ) ENGINE=InnoDB ", $str);
            $str .=";\n\n";
            //$str = $str.";\n\n--\n-- Dumping data for table `{$table}`\n--\n\n";
            $fields[$rows['Table']] = $str;
        }
        return $fields;
    }
    //获取表中的数据
    public function getDataByTable($table) {
        $data = array();
        $str = '';
        $res = mysql_query("SELECT * FROM `{$table}`", $this->conn);
        if(!$res) die('MySQL Error: ' . mysql_error());
        while($rows = mysql_fetch_assoc($res)) {
            if(!empty($rows)) {
                $data[] = $rows;
            }
        }
        $keys = array_keys($data[0]);
        foreach ($keys as $k=>$v) {
            $keys[$k] = '`'.$v.'`';
        }
        $key = join(', ', $keys);
        $str = "INSERT INTO `{$table}` ({$key}) VALUES\n";
        foreach ($data as $k=>$v) {
            $str.="(";
            while (list($key, $val) = each($v)) {
                if(!is_numeric($val)) {
                    $str.= "'".$val."', ";
                } else {
                    $str.= $val.', ';
                }
            }
            $str = substr($str, 0, -2);// 后边有空格 所以从-2 开始截取
            if($k+1 == count($data)) {
                $str.=");\n\n-- --------------------------------------------------------\n\n";
            } else {
                $str.="),\n";
            }
        }
        return $str;
    }
     //备份数据库
    public function getBackUpDataByTable ($tables, $path='', $fileName = 'seocheck', $subsection = '2') {
        if(empty($tables)) $this->_showMsg('未能指定要备份的表!!!', true);
        $page = 0;//卷数
        $path = empty($path) ? $_SERVER['DOCUMENT_ROOT'].'/core/Runtime/Data/'.$fileName.'Demo/' : $path;
        if(!file_exists($path)) {
            mkdir($path, 0777, true);
        }
        $mysql_info = $this->_retrieve();
        $fieldsByTable = array();
        if(is_array($tables)) {
            $this->_showMsg('开始备份,数据正在初始化中,请勿关闭浏览器...');
            $fw = $this->writeFileByBackUpData($path.$this->dbName.'_table.sql', $mysql_info, $method="ab+");
            if($fw !== false) {
                $this->_showMsg('备份数据库基本信息成功。。。');
            }
            foreach ($tables as $table) {
                $tableInfo = $this->getFieldsByTable($table);
                if(!empty($tableInfo)) {
                    $this->_showMsg('获取表['.$table.']结构成功。。。');
                    $fw = $this->writeFileByBackUpData($path.$this->dbName.'_table.sql', $tableInfo[$table], $method="ab+");
                    if($fw === false) {
                        $this->_showMsg('备份表['.$table.']结构失败。。。', true);
                    } else {
                        $this->_showMsg('备份表['.$table.']结构成功,开始获取数据。。。');
                    };
                } else {
                    $this->_showMsg('获取数据库['.$this->dbName.']表结构失败,请稍后再试!。。。', true);
                }
                $this->_insertSqlByTableForAll($path, $table, $subsection);
            }
        } else {
            $this->_showMsg('开始备份,数据正在初始化中,请勿关闭浏览器...');
            $tableInfo = $this->getFieldsByTable($tables);
            if(!empty($tableInfo)) {
                $this->_showMsg('获取表['.$tables.']结构成功。。。');
                $fw = $this->writeFileByBackUpData($path.$this->dbName.'_'.$tables.'_table.sql', $mysql_info.$tableInfo[$tables]);
                if($fw === false) {
                    $this->_showMsg('备份表['.$tables.']结构失败。。。', true);
                } else {
                    $this->_showMsg('备份表['.$tables.']结构成功,开始获取数据。。。');
                }
            } else {
                $this->_showMsg('获取表['.$tables.']结构失败,请稍后再试!。。。', true);
            }
            $res = $this->_insertSqlByTableForAll($path, $tables, $subsection);
        }
    }
    //数据库基本信息
    private function _retrieve() {
        $backUp  = '';
        $backUp .= '--' . "\n";
        $backUp .= '-- MySQL database dump' . "\n";
        $backUp .= '-- Created by DbBackUp class, Power By chujiu. ' . "\n";
        $backUp .= '--' . "\n";
        $backUp .= '-- 主机: ' . $this->host . "\n";
        $backUp .= '-- 生成日期: ' . date ( 'Y' ) . ' 年  ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'H:i' ) . "\n";
        $backUp .= '-- MySQL版本: ' . mysql_get_server_info () . "\n";
        $backUp .= '-- PHP 版本: ' . phpversion () . "\n";
        $backUp .= "\n\n";
        $backUp .= "SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';\n";
        $backUp .= "SET time_zone = '+00:00';\n\n";
        $backUp .= "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n";
        $backUp .= "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n";
        $backUp .= "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n";
        $backUp .= "/*!40101 SET NAMES utf8*/;\n\n";
        $backUp .= "--\n-- Database: `{$this->dbName}`\n--\n\n-- --------------------------------------------------------\n\n";
        return $backUp;
    }
    /**
     * 插入单条记录
     *
     * @param string $row
     */
    private function _insertSql($row, $table) {
        // sql字段逗号分割
        $insert = '';
        $insert .= "INSERT INTO `" . $table . "` VALUES(";
        foreach($row as $key=>$val) {
            $insert .= "'".$val."',";
        }
        $insert = substr($insert, 0 ,-1);
         $insert .= ");" . "\n";
        return $insert;
    }
    /**
     * 生成一个表的inser语句
     * @param string $table
     * @param string $subsection 分卷大小
     */
    private function _insertSqlByTableForAll($path, $table, $subsection) {
        $i = 0;
        $insertSqlByTable = '';
        $res = mysql_query("SELECT * FROM `{$table}`", $this->conn);
        if(!$res) die('MySQL Error: ' . mysql_error());
        while($rows = mysql_fetch_assoc($res)) {
            $insertSqlByTable .= $this->_insertSql($rows, $table);
            $size = strlen($insertSqlByTable);
            if($size > $subsection*1024*1024) {
                $fw = $this->writeFileByBackUpData($path.$table.$i.$this->tag.'.sql', $insertSqlByTable);
                if($fw === false) $this->_showMsg('数据库表['.$table.'],卷 '.$i.' 写入文件失败,请稍后再试!!!',true);
                $this->_showMsg('数据库表['.$table.'],卷 '.$i.' 备份成功!备份文件:[ '.$path.$table.$i.$this->tag.'.sql ]');
                $insertSqlByTable = '';
                $i+=1;
            }
        }
        // insertSqlByTable大小不够分卷大小
        if ($insertSqlByTable != "") {
            $fw = $this->writeFileByBackUpData($path.$table.$this->tag.'.sql', $insertSqlByTable);
            if($fw === false) $this->_showMsg('数据库表['.$table.']写入文件失败,请稍后再试!!!备份文件:[ '.$path.$table.$this->tag.'.sql ]',true);
            $this->_showMsg('数据库表['.$table.'] 备份成功!备份文件:[ '.$path.$table.$this->tag.'.sql ]');
        }
        $this->_showMsg('数据库表['.$table.']全部备份成功!');
    }
    // 写入文件
    public function writeFileByBackUpData($fileName, $data, $method="rb+", $iflock=1, $check=1, $chmod=1){
        $check && @strpos($fileName, '..')!==false && exit('Forbidden');
        @touch($fileName);
        $handle = @fopen($fileName, $method);
        if($iflock) {
            @flock($handle,LOCK_EX);
        }
        $fw = @fwrite($handle,$data);
        if($method == "rb+") ftruncate($handle, strlen($data));
        fclose($handle);
        $chmod && @chmod($fileName,0777);
        return $fw;
    }
    /**
     * path: 生成压缩包的路径
     * fileName : 要压缩的文件名 通常和path 同一目录
     */
    public function createZipByBackUpFile($path) {
        $db_base_files = $this->getFileByBackUpDir($path);
        if(!empty($db_base_files)) {
            $zip = new ZipArchive;
            if($zip->open($path.$this->dbName.date('Ymd').'.zip', ZipArchive::CREATE | ZIPARCHIVE::OVERWRITE) !== true) 
                die ("cannot open".$this->dbName.date('Ymd')."zip for writing.");
            foreach ($db_base_files as $key => $value) {
                if(is_file($value)) {
                    $file_name = basename($value);
                    $info[] = $zip->addFile($value, $file_name);// 避免压缩包里有文件的路径
                }
            }
            $zip->close();
            if(file_exists($path.$this->dbName.date('Ymd').'.zip'))
            foreach ($db_base_files as $val) {
                unlink($val);
            }
            if(count(array_filter($info)) > 0) return true;
        }
        return false;
    }
    //获取文件
    public function getFileByBackUpDir($path) {
        $info = array();
        $db_base_files = array();
        if( @file_exists($path) && is_dir($path) ) {
            if ($dh = opendir($path)) {
                while (($file = readdir($dh)) !== false) {
                    if($file != '.' && $file != '..') {
                        if( strripos($file, 'seocheck') !== false ) {
                            $db_base_files[] = $path.$file;
                        }
                    }
                }
                closedir($dh);
            }
        }
        return $db_base_files;
    }
    /**
     * @path: 生成压缩包的路径
     * @fileName : 要解压的文件名 默认解压到path 目录
     */
    public function uncompressZip($path, $zipName) {
        $path = empty($path) ? $_SERVER['DOCUMENT_ROOT'].'/core/Runtime/Data/' : $path;
        $zip = new ZipArchive;
        if ($zip->open($path.$zipName) === TRUE) {
            $zip->extractTo($path);
            $zip->close();
            return true;
        } else {
            return false;
        }
    }
    //导入数据库
    public function importingDataBySqlFile () {
    }
    //  及时输出信息
    private function _showMsg($msg,$err=false){
        if($err === true) {
            echo "<p style='font-size:14px;'><span style='color:red;'>ERROR: --- " . $msg . "</span></p>";exit;
        }
        echo "<p style='font-size:14px;'><span style='color:green;'>OK: --- " . $msg . "</span></p>";
    }
    // 锁定数据库,以免备份或导入时出错
    private function lock($table, $op = "WRITE") {
        if (mysql_query ( "lock tables " . $table . " " . $op ))
            return true;
        else
            return false;
    }
    // 解锁
    private function unlock() {
        if (mysql_query ( "unlock tables" ))
            return true;
        else
            return false;
    }
    // 析构
    public function __destruct() {
        if($this->conn){
            mysql_query ( "unlock tables", $this->conn );
            mysql_close ( $this->conn );
        }
    }
}
?>
PHP 相关文章推荐
PHP+MySQL5.0中文乱码解决方法
Nov 20 PHP
将文件夹压缩成zip文件的php代码
Dec 14 PHP
PHP连接sql server 2005环境配置及问题解决
Aug 08 PHP
php实现的替换敏感字符串类实例
Sep 22 PHP
PHP实现中文圆形印章特效
Jun 19 PHP
PHP里的单例类写法实例
Jun 25 PHP
php邮件发送的两种方式
Apr 28 PHP
Symfony2学习笔记之插件格式分析
Mar 17 PHP
php array_values 返回数组的值实例详解
Nov 17 PHP
php+ajax简单实现全选删除的方法
Dec 06 PHP
php利用嵌套数组拼接与解析json的方法
Feb 07 PHP
php字符串过滤strip_tags()函数用法实例分析
Jun 24 PHP
dedecms函数分享之获取某一栏目所有子栏目
May 19 #PHP
ECMall支持SSL连接邮件服务器的配置方法详解
May 19 #PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
May 19 #PHP
php开启openssl的方法
May 15 #PHP
PHP整数取余返回负数的相关解决方法
May 15 #PHP
PHP取余函数介绍MOD(x,y)与x%y
May 15 #PHP
php实例分享之通过递归实现删除目录下的所有文件详解
May 15 #PHP
You might like
php输出表格的实现代码(修正版)
2010/12/29 PHP
推荐25款php中非常有用的类库
2014/09/29 PHP
PHP扩展框架之Yaf框架的安装与使用
2016/05/18 PHP
Laravel学习教程之request validation的编写
2017/10/25 PHP
转自Jquery官方 jQuery1.1.3发布,速度提升800%,体积保持20K
2007/08/19 Javascript
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
JS实现让访问者自助选择网页文字颜色的方法
2015/02/24 Javascript
如何在Linux上安装Node.js
2016/04/01 Javascript
js实现对table的增加行和删除行的操作方法
2016/10/13 Javascript
jQuery插件ajaxFileUpload使用详解
2017/01/10 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
2018/03/06 Javascript
vue slots 组件的组合/分发实例
2018/09/06 Javascript
重学JS 系列:聊聊继承(推荐)
2019/04/11 Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
2020/05/14 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
python f-string式格式化听语音流程讲解
2019/06/18 Python
python GUI图形化编程wxpython的使用
2019/07/19 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
Pycharm内置终端及远程SSH工具的使用教程图文详解
2020/03/19 Python
python进度条显示-tqmd模块的实现示例
2020/08/23 Python
Python Selenium自动化获取页面信息的方法
2020/08/31 Python
Html5 web本地存储实例详解
2016/07/28 HTML / CSS
香港化妆品经销商:我的公主
2016/08/05 全球购物
全球最大最受欢迎的旅游社区:Tripadvisor
2017/11/03 全球购物
时尚圣经:The Fashion Bible
2019/03/03 全球购物
测绘工程个人的自我评价
2013/11/10 职场文书
大学生职业生涯规划范文
2014/01/22 职场文书
领导接待方案
2014/03/13 职场文书
新法人代表任命书
2014/06/06 职场文书
英语教师求职信
2014/06/16 职场文书
公司领导班子群众路线四风问题对照检查材料
2014/10/02 职场文书
整改报告怎么写
2014/11/06 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
CSS list-style-type属性使用方法
2023/05/21 HTML / CSS