【码】PHP导入导出MongoDB数据库
in 代码片段 with 0 comment

【码】PHP导入导出MongoDB数据库

in 代码片段 with 0 comment

本段代码源于 gitHub项目
说明:笔者在源项目的基础上增加了数据导入功能,同时将压缩数据包的类库换成了ZipArchive,主要是因为 RecursiveIteratorIterator这个库太冷,笔者真的不太会,直接简单粗暴的换了。

<?php
<?php
namespace MyOrg\DbTools;
use Think\Log;

/**
 * This class allows you to dump any local mongoDB database, utilizing shell command
 * to do so. If there is an error, please verify that the backup folder has the
 * correct permissions and this script has execute permissions.
 *
 * $tool = new MongoTool('/data/wwwroot/default/Data');
 * $tool->restore('yangshenGM2','yangshenGM2_2016-01-24_15-21.zip','',true);      //恢复指定数据库  全库恢复
 * $tool->restore('yangshenGM2','yangshenGM2_2016-01-24_15-21.zip','user',true);  //恢复指定数据表  单表恢复
 * $tool->backUp('yangshenGM2','',true);      //备份指定数据库         全库备份
 * $tool->backUp('yangshenGM2','user',true);  //备份指定数据库和数据表  单表备份
 *
 * 值得注意的是,备份和恢复是需要配套使用的!
 */

/**
 * Mongo数据库备份恢复类库
 * Class MongoTool
 * @package MyOrg\DbTools
 */
class MongoTool {

    private $targetPath; //最终zip包存放的地方
    private $_DATE_TIME; //当前格式化了的时间,精确到分钟
    private $workPath;   //打包的路径,这里将最终确定zip包的目录结构
    private $config;     //数据库配置
    private $tbName;     //数据表名称
    private $tmpPath;    //用于存储中间导出的数据文件,在zip之后这里的文件会被删除
    private $debug;      //是否开启debug,开启就输出调试信息


    public function __construct( $path, $config = [] ) {
        if( empty($path) ){
            E(L('_PARAM_ERROR_'));
        }
        $this->targetPath = rtrim($path, '/');
        $this->_DATE_TIME = date('Y-m-d_H-i');

        $conf = [
            'DB_TYPE' => 'mongodb',
            'DB_HOST' => '127.0.0.1',
            'DB_NAME' => 'yangshenGM',
            'DB_USER' => '',
            'DB_PWD' => '',
            'DB_PORT' => 27017,
            'DB_PREFIX' => ''
        ];
        $this->config = array_merge($conf, $config);
        
    }

    public function backUp( $tbName = '', $debug = false){
        $this->debug = $debug;
        if( !empty($tbName) ){
            $this->tbName = $tbName;
        }
        $this->tmpPath = $this->targetPath . "/" . $this->config['DB_NAME'] . "_" . $this->_DATE_TIME;
        $this->workPath = $this->tmpPath . "/" . $this->config['DB_NAME'];
        $this->echoIfDebug("Backing up '{$this->config['DB_NAME']}' to '{$this->tmpPath}'");
        $this->mongoDump();
        $this->zipFiles();
        $this->deleteTmpDir($this->tmpPath);
        $this->echoIfDebug("Complete!");
    }

    public function restore( $fileName = '', $tbName = '', $debug = false){
        $this->debug = $debug;
        if( !empty($tbName) ){
            $this->tbName = $tbName;
        }
        if( empty($fileName) ){
            E(L('_PARAM_ERROR_'));
        }
        $this->tmpPath = $this->targetPath . "/" . $fileName;
        $this->echoIfDebug("Restoring '{$this->config['DB_NAME']}' from '{$this->tmpPath}'");
        $this->unzipFiles();
        $this->mongoRestore();
        $dir = $this->targetPath . '/tmp';
        $this->deleteTmpDir($dir);
        $this->echoIfDebug("Complete!");
    }

    private function echoIfDebug( $string ) {
        if ($this->debug) {
            Log::record($string,'DEBUG',true);
        }
    }

    private function mongoDump() {
        $this->echoIfDebug("Executing mongodump...");
        if( empty($this->tbName) ){
            if( $this->config['DB_USER'] ){
                $command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} --out " . $this->tmpPath;
            }else{
                $command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --out " . $this->tmpPath;
            }
        }else{
            if( $this->config['DB_USER'] ){
                $command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --collection {$this->tbName} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} --out " . $this->tmpPath;
            }else{
                $command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --collection {$this->tbName} --db {$this->config['DB_NAME']} --out " . $this->tmpPath;
            }
        }
        $results = shell_exec($command);
        $this->echoIfDebug("Command:{$command},Result:{$results}");
    }

    private function mongoRestore() {
        $this->echoIfDebug("Executing mongorestore...");
        if( empty($this->tbName) ){
            if( $this->config['DB_USER'] ){
                $command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} {$this->targetPath}/tmp";
            }else{
                $command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} {$this->targetPath}/tmp";
            }
        }else{
            if( $this->config['DB_USER'] ){
                $command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --collection {$this->tbName} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} {$this->targetPath}/tmp/{$this->tbName}.bson";
            }else{
                $command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --collection {$this->tbName} {$this->targetPath}/tmp/{$this->tbName}.bson";
            }
        }
        $results = shell_exec($command);
        $this->echoIfDebug("Command:{$command},Result:{$results}");
    }

    private function zipFiles() {
        $this->echoIfDebug("Zipping files...");
        chdir($this->workPath);
        $zip = new \ZipArchive;
        $zip->open($this->targetPath. '/' . $this->config['DB_NAME'] .'_'. $this->_DATE_TIME . '.zip', \ZipArchive::CREATE);
        $dir = opendir($this->workPath);
        while( $file = readdir($dir) ){
            if( $file != '.' && $file != '..' ){
                $zip->addFile($file);
                $this->echoIfDebug("{$file} has been zip");
            }
        }
        $zip->close();
    }

    private function unzipFiles() {
        $this->echoIfDebug("unzipping files...");
        chdir($this->targetPath);
        $zip = new \ZipArchive;
        $zip->open($this->tmpPath);
        $zip->extractTo('tmp');
        $zip->close();
    }

    private function deleteTmpDir( $dir ) {
        $this->echoIfDebug("Deleting {$dir} ...");
        $files = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
            \RecursiveIteratorIterator::CHILD_FIRST
        );
        foreach ( $files as $file ) {
            $file->isDir() ? rmdir($file) : unlink($file);
        }
        rmdir($dir);
    }
}
Comments are closed.