yii databasebackup extension 数据库备份扩展制作

由于目前Yii官网没有数据库备份扩展,而我目前有此需要,故自己想办法解决。

网上能找到PHP上的Mysql备份还原类,但全都是针对MyISAM引擎,而我需要对innoDB引擎的数据库进行备份,所以只有自己想办法。

如果你用的是MyISAM引擎,那信手拈来,把connet,query改为Yii::app()->db->createCommand($sql)即可,具体可参考本文最底部的参考资料。

innoDB实现思路:

寻找外键foreign key,决定备份和还原的顺序,先备份有外键的表,再备份无外键的表,都有外键,按相互关系。

我目前还没想到从foreign key决定顺序的好办法,所以此次代码编写仅采用半自动的方法。
例:如果A表有外键是B表的主键,B表有外键是C表的主键。则我们先定顺序A>B>C。

1、实现DROP:正序DROP,即DROP TABLE A; DROP TABLE B; DROP TABLE C;

2、实现CREATE:反序CREATE,即C>B>A;

3、实现数据还原:反序还原,即先运行C表的所有insert命令,再B表,最后A表。

我的代码:

1、编写自己的init文件,里面写的是建初始数据库的create语句,为myInit.sql;

2、DatabaseBackup类代码:

<?php 
  
class DatabaseBackup{
     
    //备份函数
    public static function backupDb($filepath, $tables = '*') {
        if ($tables == '*') {
            $tables = array();
            $tables = Yii::app()->db->schema->getTableNames();
        } else {
            $tables = is_array($tables) ? $tables : explode(',', $tables);
        }
        $return = '';
 
        foreach ($tables as $table) {
            $result = Yii::app()->db->createCommand('SELECT * FROM ' . $table)->query();
            foreach ($result as $row) {
                $return.= 'INSERT INTO ' . $table . ' VALUES(';
                foreach ($row as $data) {
                    $data = addslashes($data);
 
                    // Updated to preg_replace to suit PHP5.3 +
                    $data = preg_replace("/\n/", "\\n", $data);
                    if (isset($data)) {
                        $return.= '"' . $data . '"';
                    } else {
                        $return.= '""';
                    }
                    $return.= ',';
                }
                $return = substr($return, 0, strlen($return) - 1);
                $return.= ");\n";
            }
            $return.="\n";
        }
        //save file
        $handle = fopen($filepath, 'w+');
        fwrite($handle, $return);
        fclose($handle);
    }
     
    //还原函数
    public static function recoverDb($filepath, $tables = '*') {
        //设置时间限制为0,即不强制停止
        set_time_limit(0);
         
         
        //采用事务,导入出错则回滚
        $transaction = Yii::app()->db->beginTransaction();
        try{
            $sqls='';
             
            //反转备份表顺序
            $tables=explode(',', DBBACKUP_TABLES);
            $tables=array_reverse($tables);
             
            //删除所有表
            foreach($tables as $table){
                $sqls.='DROP TABLE '.$table.";\n";
            }
            $sqls.="\n\n";
             
            //读取结构
            $dbModelFile=DBBACKUP_PATH.'/myInit.sql';
            $handle=@fopen($dbModelFile,'r');
            $sqls.=fread($handle, filesize($dbModelFile));
            fclose($handle);
            $sqls.="\n\n";
             
            //读取备份
            $handle=@fopen($filepath,'r');
            $sqls.=fread($handle, filesize($filepath));
            fclose($handle);
            //echo $sqls;
             
            Yii::app()->db->createCommand($sqls)->query();
            $transaction->commit();
            return true;
        }
        catch (Exception $e) {
            $transaction->rollback(); //如果操作失败, 数据回滚
            return false;
        }
    }
}

3、定义备份顺序:

$tables="admin,category,gallary,content,photo,comment,feedback";

4、备份执行代码:

DatabaseBackup::backupDb(DBBACKUP_PATH.'/filename.sql',$tables);

5、还原执行代码:

DatabaseBackup::recoverDb(DBBACKUP_PATH.'/filename.sql',$tables);

参考:http://www.yiiframework.com/forum/index.php/topic/29291-full-database-backup/

若您觉得我的博文对您有帮助,欢迎点击下方按钮对我打赏
打赏