zoukankan      html  css  js  c++  java
  • PHP数据库分卷导出备份的实现思路

    在写这个功能的时候借鉴了诸多系统,例如dedeCMS,phpCMS等系统,可惜如出一辙,都有bug,他们没办法很好的控制住分卷的大小,所以自己冥思苦想,最总有了一下思路:

    //如果要轉載本文請注明出處,免的出現版權紛爭,我不喜歡看到那種轉載了我的作品卻不注明出處的人 Seven{See7di#Gmail.com}
    $work=StrToLower(_r($_GET["work"]));
    Switch ($work){
    Case "export":
    _Export();
    Break;
    Case "exportloop":
    _ExportLoop();
    Break;
    Case "tozip":
    _Tozip();
    Break;
    }
    /*---------------------------------*/
    Function _Export(){
    Global $Mysql,$work;
    $f1=_r($_GET["f1"]);

    //如果是第一个回圈
    IF($f1=="1"){
       //首先获取一次是否指定了备份表
       $tables=$_REQUEST["tables"];
       Echo ($tables);
       IF(Empty($tables)){
        //得到数据表
        $Result=$Mysql->View("Show Tables From ".BLK_SysDbname."");
        Foreach($Result as $val){
         $tables[]=$val[0];
        }
       }Else{
        $tables=Explode(",", $tables);
        $tables=Array_Filter($tables,'_nul');
       }
       $_SESSION['Tab'] = $tables;

       //初始化数据表表序号
       $nList=0;
       //初始化文件序号
       $nFile=1;
       //用来做比较,看看是否已经写入建表信息
       $_SESSION['nList'] = ($nList-1);
    }Else{
       $nList=_r($_GET["nList"]);
       $nFile=_r($_GET["nFile"]);
    }
    $iSql = '';        //抓取的内容
    $fPath = "Cache/";      //保存目录
    $cName = "DB_Export.sql";    //缓存文件
    $_Tab = $_SESSION['Tab'][$nList]; //当前所操作的表
    $fName = "DB".Date('_md_').$nFile.".sql";

    //判断目录状况
    IF(!Is_writable($fPath)){Exit("数据无法备份到服务器!请检查 ".$fPath." 目录是否可写。");}

    //判断是否备份完毕
    IF(Count($_SESSION['Tab'])<=$nList){
       @Unlink($fPath.$cName);
       For($i=1;$i<=$nFile;$i++){
        $FileArr[]=$fPath."DB".Date('_md_').$i.".sql";
       }
       $_FileName="DB".Date('_md').".zip";
       Tozip($FileArr,$_FileName,2,2);

       Alert("","?work=backdb&rback=1");
       Die();
    }

    //每次读一个表,得到头信息和建表信息
    IF($_SESSION['nList'] < $nList){
       IF($nFile==1 And $nList==0){
        //删除文件
        For($i=1;$i<1000;$i++){
         IF(File_exists($fPath."DB".Date('_md_').$i.".sql")){
          @Unlink($fPath."DB".Date('_md_').$i.".sql");
         }Else{
          Break;
         }
        }
        //建立文件
        File_put_contents($fPath.$fName,"");
        File_put_contents($fPath.$cName, "");
        $iSql = "# Create by ".BLK_SysName."\n# Create time ".Date('Y-m-d')."\n# Mysql Version ".$Mysql->Version()."\n# PHP Version ".@phpversion()."\n# --------------------------------------------------------\n\nSET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\";\n";
       }
       $iSql .= "DROP TABLE IF EXISTS `".$_Tab."`;\n";
       $_iSql = Mysql_fetch_row(mysql_query("SHOW CREATE TABLE ".$_Tab.""));
       $iSql .= $_iSql[1].";\n\n";
    }

    //写入头信息
    $iSql=Trim(File_get_contents($fPath.$fName)."\n\n".$iSql);
    File_put_contents($fPath.$fName,$iSql);

    //得到缓存的内容并判断是否为空,如果为空,抓取当前表所有的内容放入缓存
    $_Cache=Trim(File_get_contents($fPath.$cName));
    IF(Empty($_Cache)){
       $_Cache=DropInfo($_Tab);
       File_put_contents($fPath.$cName,$_Cache);
    }

    //循环抓取,直到备份文件满额为止(因为循环不能及时得到文件尺寸)
    Alert("","?work=exportloop&nList=".$nList."&nFile=".$nFile."&Session=".$Session."","",10);
    }
    /*---------------------------------*/
    Function _ExportLoop(){
    Global $work;
    $nList=_r($_GET["nList"]);
    $nFile=_r($_GET["nFile"]);
    $iSql = '';        //抓取的内容
    $fPath = "Cache/";      //保存目录
    $fSize = (BLK_SysDbsplit*1024);   //文件大小,2048K=2M
    $fName = "DB".Date('_md_').$nFile.".sql";
    $cName = "DB_Export.sql";

    //显示进度
    Echo "<br><br><strong>备份正在进行中请稍候,现在正在生成 <span style='color:red;'>".$fName."</span></strong><br><br>";
    Echo "<br>".(FileSize($fPath.$fName))."<br>".$fSize."<br><br>";
    Echo Loading((FileSize($fPath.$fName)),$fSize);

    //如果备份文件满了
    IF(((FileSize($fPath.$fName))+9000)>$fSize){
       $nFile++;       //备份文件序号加一
       $_SESSION['nList'] = $nList; //防止再次写入建表信息
       Alert("","?work=export&nList=".$nList."&nFile=".$nFile."&Session=".$Session."","",30);
    }Else{
       //取得现在缓存的内容,编译为数组
       $_Cache = (File($fPath.$cName));

       //为备份文件抓取需要的数据,每次4条
       $_Info=Array();
       For($i=0;$i<2;$i++){
        $_Info[]=$_Cache[$i];
       }

       //得到新的缓存数据
       $_Cache=array_diff_key($_Cache,$_Info);
       File_put_contents($fPath.$cName,Trim(Implode("",$_Cache)));

       //重新整理备份文件的内容并写入
       $iSql=Trim(File_get_contents($fPath.$fName))."\n".Trim(Implode("",$_Info));
       File_put_contents($fPath.$fName,$iSql);

       //如果备份文件未满而缓存空了,则进入下一个表
       IF(Count($_Cache)<1){
        $nList++;
        $_SESSION['nList'] = ($nList-1);
        Alert("","?work=export&nList=".$nList."&nFile=".$nFile."&Session=".$Session."","",10);
       //如果备份文件未满而缓存未空,则循环该函数
       }Else{
        Alert("","?work=exportloop&nList=".$nList."&nFile=".$nFile."&Session=".$Session."","",10);
       }
    }
    }


  • 相关阅读:
    菜鸟nginx源码剖析数据结构篇(十一) 共享内存ngx_shm_t[转]
    菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock[转]
    菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t[转]
    菜鸟nginx源码剖析数据结构篇(八) 缓冲区链表ngx_chain_t[转]
    菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下)[转]
    菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)[转]
    菜鸟nginx源码剖析数据结构篇(五) 基数树 ngx_radix_tree_t[转]
    菜鸟nginx源码剖析数据结构篇(四)红黑树ngx_rbtree_t[转]
    菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]
    菜鸟nginx源码剖析数据结构篇(二) 双向链表ngx_queue_t[转]
  • 原文地址:https://www.cnblogs.com/see7di/p/2239908.html
Copyright © 2011-2022 走看看