ThinkPHP框架实现的MySQL数据库备份功能示例


Posted in PHP onMay 24, 2018

本文实例讲述了ThinkPHP框架实现的MySQL数据库备份功能。分享给大家供大家参考,具体如下:

1、缘由

自从2010年开始试用ThinkPHP以来,的确带来了许多方便。的确给我带来了许多方便。此次应为数据频繁备份需要,而每次远程连接到服务器颇为不便。变萌生了写个ThinkPHP数据库备份SQL生成类的念头。

2、介绍

由于在数据库中有使用触发器。因此也需要一并备份。并且为了插入数据的时候不会受到触发器影响而破坏先前插入的数据,在插入数据之前生成了删除触发器的代码。 本类并不能生成数据表的创建和删除代码,因此在使用中请注意保证两端表结构的一致。

做WEB开发,一直以来,都采用 Navicat For Mysql 将本地数据库同步到服务器上。前些天,突然心血来潮,将本地数据库升级到了 Mysql 5.5版本,再次将数据同步的时候却发生了错误。想起之前写过的 ThinkPHP 实现Mysql数据库备份 只有备份数据的功能,而没有导出表结构的功能。于是想到了升级一下。让其更完整。

本次升级 增加了 备份表结构、视图功能。导出数据增加了类型判断,insert 语句当字段为空的时候会输出 NULL,当为数字 的时候则不会带上 单引号。

<?php
/**
 * 描述:基于ThinkPHP框架的Mysql数据库导出类
 * 日期:2012-07-15
 * 作者:龚辟愚
 */
class DBExport
{
  /**
   * @description 获取当前数据库的所有表名。
   * @static
   * @return array
   */
  static protected function getTables()
  {
    $dbName=C('DB_NAME');
    $result=M()->query("SHOW FULL TABLES FROM `{$dbName}` WHERE Table_Type = 'BASE TABLE'");
    foreach ($result as $v){
      $tbArray[]=$v['Tables_in_'.C('DB_NAME')];
    }
    return $tbArray;
  }
  static protected function getViews()
  {
    $dbName=C('DB_NAME');
    $result=M()->query("SHOW FULL TABLES FROM `{$dbName}` WHERE Table_Type = 'VIEW'");
    foreach ($result as $v){
      $tbArray[]=$v['Tables_in_'.C('DB_NAME')];
    }
    return $tbArray;
  }
  /**
   * @description 导出SQL数据,但不包含表创建代码。
   * @static
   * @return string
   */
  static public function ExportAllData()
  {
    $tables = self::getTables();
    $arrAll = array(
      "SET FOREIGN_KEY_CHECKS=0;",
      self::BuildAllTriggerDropSql(),
      self::BuildTableSql(),
      self::BuildViewSql()
    );
    $tbl = new Model();
    foreach($tables as $table)
    {
      $arrAll[]="\r\nDELETE FROM {$table};";
      /*
      $rs = $tbl->query("SHOW COLUMNS FROM {$table}");
      $arrFields = array();
      foreach ($rs as $k=>&$v){
        $arrFields[] = "`{$v['Field']}`";
      }
      $sqlFields = implode($arrFields,",");
      */
      $rs=$tbl->query("select * from `{$table}`");
      foreach ($rs as $k=>&$v){
        $arrValues = array();
        foreach($v as $key=>$val)
        {
          if(is_numeric($val)){
            $arrValues[]=$val;
          }else if(is_null($val)){
            $arrValues[]='NULL';
          }else{
            $arrValues[]="'".addslashes($val)."'";
          }
        }
        $arrAll[] = "INSERT INTO `{$table}` VALUES (".implode(',',$arrValues).");";
      }
    }
    $arrAll[]=self::BuildTriggerCreateSql();
    return implode("\r\n",$arrAll);
  }
  static protected function BuildTableSql()
  {
    $tables = self::getTables();
    $arrAll = array();
    foreach($tables as &$val){
      $rs = M()->query("SHOW CREATE TABLE `{$val}`");
      $tbSql = preg_replace("#CREATE(.*)\\s+TABLE#","CREATE TABLE",$rs[0]['Create Table']);
      $arrAll[] = "DROP TABLE IF EXISTS `{$rs[0]['Table']}`;\r\n{$tbSql};\r\n";
    }
    return implode("\r\n",$arrAll);
  }
  static protected function BuildViewSql()
  {
    $views = self::getViews();
    $arrAll = array();
    foreach($views as &$val){
      $rs = M()->query("SHOW CREATE VIEW `{$val}`");
      $tbSql = preg_replace("#CREATE(.*)\\s+VIEW#","CREATE VIEW",$rs[0]['Create View']);
      $arrAll[] = "DROP VIEW IF EXISTS `{$rs[0]['View']}`;\r\n{$tbSql};\r\n";
    }
    return implode("\r\n",$arrAll);
  }
  /**
   * @description 如果存在触发器,生成删除代码。原因是:插入数据的时候可能会受到触发器影响。
   * @static
   * @return string
   */
  static public function BuildAllTriggerDropSql()
  {
    $rs = M()->query("show triggers");
    $arrAll = array();
    foreach ($rs as $k=>&$v)
    {
      $arrSql = array(
        'DROP TRIGGER IF EXISTS `',$v['Trigger'],'`;'
      );
      $arrAll[] = implode('',$arrSql);
    }
    return implode("\r\n",$arrAll);
  }
  /**
   * @description 生成所有触发器的创建代码。
   * @static
   * @return string
   */
  static protected function BuildTriggerCreateSql()
  {
    $rs = M()->query("show triggers");
    $arrAll = array();
    foreach ($rs as $k=>&$v)
    {
      $arrSql = array(
        'CREATE TRIGGER `',$v['Trigger'],'` ',$v['Timing'],' ',$v['Event'],' ON `',
        $v['Table'],'` FOR EACH ROW ',$v['Statement'],';'
      );
      $arrAll[] = implode('',$arrSql);
    }
    return implode("\r\n",$arrAll);
  }
}

调用示例:

vendor('DBExport',COMMON_PATH);
header('Content-type: text/plain; charset=UTF-8');
$dbName = C('DB_NAME');
header("Content-Disposition: attachment; filename=\"{$dbName}.sql\"");
echo DBExport::ExportAllData()

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
用PHP实现文件上传二法
Oct 09 PHP
Session的工作方式
Oct 09 PHP
在同一窗体中使用PHP来处理多个提交任务
May 08 PHP
php设计模式 Builder(建造者模式)
Jun 26 PHP
PHP文章按日期(月日)SQL归档语句
Nov 29 PHP
zend framework文件上传功能实例代码
Dec 25 PHP
PHP利用MySQL保存session的实现思路及示例代码
Sep 09 PHP
使用PHP实现生成HTML静态页面
Nov 18 PHP
YiiFramework入门知识点总结(图文教程)
Dec 28 PHP
在WordPress中安装使用视频播放器插件Hana Flv Player
Jan 04 PHP
PHPMailer ThinkPHP实现自动发送邮件功能
Jun 10 PHP
php微信公众号开发之简答题
Oct 20 PHP
CI框架(CodeIgniter)实现的导入、导出数据操作示例
May 24 #PHP
PHP实现一维数组与二维数组去重功能示例
May 24 #PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
May 23 #PHP
yii2安装详细流程
May 23 #PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
May 23 #PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
May 23 #PHP
PHP工厂模式简单实现方法示例
May 23 #PHP
You might like
php模拟js函数unescape的函数代码
2012/10/20 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
PHP结合jQuery实现找回密码
2015/07/22 PHP
Node.js:Windows7下搭建的Node.js服务(来玩玩服务器端的javascript吧,这可不是前端js插件)
2011/06/27 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
jQuery setTimeout传递字符串参数报错的解决方法
2014/06/09 Javascript
node.js中的console.time方法使用说明
2014/12/09 Javascript
JavaScript中的null和undefined区别介绍
2015/01/01 Javascript
JS判断页面是否出现滚动条的方法
2015/07/17 Javascript
JQuery实现鼠标滚轮滑动到页面节点
2015/07/28 Javascript
JavaScript实现快速排序的方法
2015/07/31 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
2016/06/27 Javascript
浅谈jquery设置和获得checkbox选中的问题
2016/08/19 Javascript
JavaScript实现的XML与JSON互转功能详解
2017/02/16 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
2017/05/11 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
vue中如何创建多个ueditor实例教程
2017/11/14 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
[01:54]TI4西雅图DOTA2选手欢迎晚宴 现场报道
2014/07/08 DOTA
python实现的一个p2p文件传输实例
2014/06/04 Python
简介Django中内置的一些中间件
2015/07/24 Python
Python实现文件内容批量追加的方法示例
2017/08/29 Python
Python文件操作之合并文本文件内容示例代码
2017/09/19 Python
python读取一个目录下所有txt里面的内容方法
2018/06/23 Python
python 使用值来排序一个字典的方法
2018/11/16 Python
python里dict变成list实例方法
2019/06/26 Python
基于python分析你的上网行为 看看你平时上网都在干嘛
2019/08/13 Python
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
社团2014年植树节活动总结
2014/03/11 职场文书
创业计划书之水果店
2019/07/18 职场文书
掌握一个领域知识,高效学习必备方法
2019/08/08 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS
WebWorker 封装 JavaScript 沙箱详情
2021/11/02 Javascript