站长资讯网
最全最丰富的资讯网站

php如何实现更新功能

php实现更新功能的方法:首先制作升级包,增量更新;然后验证上传文件,并验证当前系统版本;接着备份原来的代码,并当升级失败时进行回滚;最后记录升级日志,返回升级进度即可。

php如何实现更新功能

推荐:《PHP视频教程》

php 实现一个简单的项目升级功能

思路

1.制作升级包,增量更新

2.升级包上传验证上传文件,验证当前系统版本

3.升级之前要先备份原来的代码,升级失败要进行回滚

4.记录升级日志,返回升级进度

5.升级包应该是加密的(暂时没实现)

说明

1.升级包的目录结构必须如下

/**  *  升级包规定的目录结构  *  xxx_版本号.zip(如:xxx_1.0.0.zip)  *   |  *   |————mysql  *   |    |  *   |    |___mysql_update.sql(更新脚本)  *   |    |___mysql_rockback.sql(回滚脚本)  *   |      *   |____php  *  */

2.mysql_update.sql

create table test(id init(11)); create table test2(id init(11)); mysql_rockback.sql drop table test; drop table test2; 4.代码 class UpgradeSys{     public $update_log = "/tmp/web/update_log.log"; //系统升级日志     public $return_log = "/tmp/web/return_log.log"; //系统回滚日志     public $progress_log = "/tmp/web/progress_log.log"; //记录进度     public $root_dir = "/Users/feng/Documents/work/test"; //站点代码的根目录     public $aFile = ["log","runtime"];//忽略文件夹相对路径     public $backup_dir = "/tmp/web/backup_dir";//备份目录     public $upload_dir = "/tmp/web/upload_dir";//升级包目录     public $sys_version_num = '1.0.0';//当前系统的版本 这个在实际应用中应该是虫数据库获取得到的,这里只是举个例子     /** 展示升级界面 */     public function index()     {         include("update.html");     }     /**      * 处理升级包上传      */     public function upload()     {         $params = $_POST;         if($_FILES)         {             $name  = $_FILES['file']['tmp_name'];             if(!$name || !is_uploaded_file($name))             {                 echo json_encode(["status"=>0,"msg"=>"请上传升级包文件"]);                 die;             }         }         //校验后缀         $astr = explode('.',$name);         $ext = array_pop($astr);         if($ext != 'zip')         {             echo json_encode(["status"=>0,"msg"=>"请上传文件格式不对"]);             die;         }         //校验升级密码         // if(!isset($params['password']) || $params['password'] != $this->password)         // {         //     echo json_encode(["status"=>0,"msg"=>"密码错误"]);         //     die;         // }         //对比版本号         $astr = explode('_',$name);         $version_num = str_replace(".zip", '',array_pop($astr));         if(!$version_num)         {             echo json_encode(["status"=>0,"msg"=>"获取版本号失败"]);             die;         }         //对比         if(!$this->compare_version($version_num))         {             echo json_encode(["status"=>0,"msg"=>"不能升级低版本的"]);             die;         }         $package_name = $this->upload_dir.'/'.$version_num.'.zip';         if(!move_uploaded_file($name,$package_name))         {             echo json_encode(["status"=>0,"msg"=>"上传文件失败"]);             die;         }         //记录下日志         $this->save_log("上传升级包成功!");         $this->update_progress("20%");         //备份code         $result = $this->backup_code();         if(!$result)         {             $this->save_log("备份失败!");             echo json_encode(["status"=>0,"msg"=>"备份失败"]);             die;         }         $this->update_progress("30%");         //执行升级         $this->execute_update($package_name);     }     /**      * 升级操作      * @return [type] [description]      */     private function execute_update($package_name)     {         //解压 如何使用zip加密压缩,这里解压缩的时候注意要解密         exec(" cd $upload_dir && unzip $package_name ");         $package_name = str_replace(".zip","",$package_name);         if(!is_dir($package_name))         {             $this->save_log("解压失败");             echo json_encode(["status"=>0,"msg"=>"解压失败"]);             die;         }         $this->update_progress("50%");         //升级mysql         if(file_exists($this->upload_dir.'/'.$package_name."/mysql/mysql_update.sql"))         {             $result = $this->database_operation($this->upload_dir.'/'.$package_name."/mysql/mysql_update.sql");             if(!$result['status'])             {                 echo json_encode($result);die;             }         }         $this->update_progress("70%");         //升级PHP         if(is_dir($this->upload_dir.'/'.$package_name.'/php'))         {             exec("cd {$this->upload_dir}/{$package_name}/php && cp -rf ./* $this->root_dir ",$mdata,$status);             if($status != 0 )             {                 $this->save_log("php更新失败");                 //数据库回滚                 if(file_exists($this->upload_dir.'/'.$package_name."/mysql/mysql_rockback.sql"))                 {                     $this->save_log("数据库回滚");                     $this->database_operation($this->upload_dir.'/'.$package_name."/mysql/mysql_rockback.sql");                                   }                 //php代码回滚                 $cmd = "cp -rf " .$this->backup_dir."/".$this->sys_version_num.'/'.basename($this->root_dir)."/* ".$this->root_dir;                 exec($cmd,$mdata,$status);                 $this->save_log("php回滚");                 echo json_encode(["status"=>0,"msg"=>"php更新失败"]);                 die;             }         }         //把解压的升级包清除         exec("rm -rf $upload_dir/$package_name ");                  $this->update_progress("100%");         //更新系统的版本号了        //更新php的版本号了(应该跟svn/git的版本号一致)        //更新数据库的版本号了(应该跟svn/git的版本号一致)         echo json_encode(["status"=>1,"msg"=>"升级成功"]);         die;     }     /**      * 比较代码版本      * @return [type] [description]      */     private function compare_version($version_num='1.0.0')     {                  return version_compare($version_num,$this->sys_version_num,'>');     }     /**      * 备份代码      */     private function backup_code()     {         //rsync 要确定系统是否已经安装         $cmd = "cd $root_dir && cd ..  && rsync -av ";         foreach ($this->aFile as $key => $value) {             $cmd ."--exclude ". basename($this->root_dir) ."/".$value ." ";         }         $cmd .= basename($this->root_dir)." ".$this->backup_dir."/".$this->sys_version_num;         exec($cmd,$mdata,$status);         if($status != 0)         {             return false;         }         //这里还可以对备份的文件进行压缩         return true;     }     /**      * 数据库操作      */     public function database_operation($file)     {         $mysqli = new mysqli("localhost","root","root","test");         if($mysqli->connect_errno)         {             return ["status"=>0,"msg"=>"Connect failed:".$mysqli->connect_error];         }         $sql = file_get_contents($file);         $a = $mysqli->multi_query($sql);         return ["status"=>1,"msg"=>"数据库操作OK"];     }     /**      * 返回系统升级的进度      */     public function update_progress($progress)     {         exec(" echo '".$progress."' > $this->progress_log ");     }     /**      * 记录日志      */     public function save_log($msg,$action="update")     {         $msg .= date("Y-m-d H:i:s").":".$msg."n";         if($action == "update")         {             exec(" echo '".$msg."' >>  $this->update_log ");         }else         {             exec(" echo '".$msg."' >>  $this->return_log ");         }     } }

赞(0)
分享到: 更多 (0)