php實(shí)現(xiàn)更新功能的方法?這個(gè)問(wèn)題可能是我們?nèi)粘W(xué)習(xí)或工作經(jīng)常見(jiàn)到的。希望通過(guò)這個(gè)問(wèn)題能讓你收獲頗深。下面是小編給大家?guī)?lái)的參考內(nèi)容,讓我們一起來(lái)看看吧!
創(chuàng)新互聯(lián)公司專注于池州企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站定制開(kāi)發(fā)。池州網(wǎng)站建設(shè)公司,為池州等地區(qū)提供建站服務(wù)。全流程按需開(kāi)發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
php實(shí)現(xiàn)更新功能的方法:首先制作升級(jí)包,增量更新;然后驗(yàn)證上傳文件,并驗(yàn)證當(dāng)前系統(tǒng)版本;接著備份原來(lái)的代碼,并當(dāng)升級(jí)失敗時(shí)進(jìn)行回滾;最后記錄升級(jí)日志,返回升級(jí)進(jìn)度即可。
php 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的項(xiàng)目升級(jí)功能
思路
1.制作升級(jí)包,增量更新
2.升級(jí)包上傳驗(yàn)證上傳文件,驗(yàn)證當(dāng)前系統(tǒng)版本
3.升級(jí)之前要先備份原來(lái)的代碼,升級(jí)失敗要進(jìn)行回滾
4.記錄升級(jí)日志,返回升級(jí)進(jìn)度
5.升級(jí)包應(yīng)該是加密的(暫時(shí)沒(méi)實(shí)現(xiàn))
說(shuō)明
1.升級(jí)包的目錄結(jié)構(gòu)必須如下
/** * 升級(jí)包規(guī)定的目錄結(jié)構(gòu) * xxx_版本號(hào).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"; //系統(tǒng)升級(jí)日志 public $return_log = "/tmp/web/return_log.log"; //系統(tǒng)回滾日志 public $progress_log = "/tmp/web/progress_log.log"; //記錄進(jìn)度 public $root_dir = "/Users/feng/Documents/work/test"; //站點(diǎn)代碼的根目錄 public $aFile = ["log","runtime"];//忽略文件夾相對(duì)路徑 public $backup_dir = "/tmp/web/backup_dir";//備份目錄 public $upload_dir = "/tmp/web/upload_dir";//升級(jí)包目錄 public $sys_version_num = '1.0.0';//當(dāng)前系統(tǒng)的版本 這個(gè)在實(shí)際應(yīng)用中應(yīng)該是蟲(chóng)數(shù)據(jù)庫(kù)獲取得到的,這里只是舉個(gè)例子 /** 展示升級(jí)界面 */ public function index() { include("update.html"); } /** * 處理升級(jí)包上傳 */ public function upload() { $params = $_POST; if($_FILES) { $name = $_FILES['file']['tmp_name']; if(!$name || !is_uploaded_file($name)) { echo json_encode(["status"=>0,"msg"=>"請(qǐng)上傳升級(jí)包文件"]); die; } } //校驗(yàn)后綴 $astr = explode('.',$name); $ext = array_pop($astr); if($ext != 'zip') { echo json_encode(["status"=>0,"msg"=>"請(qǐng)上傳文件格式不對(duì)"]); die; } //校驗(yàn)升級(jí)密碼 // if(!isset($params['password']) || $params['password'] != $this->password) // { // echo json_encode(["status"=>0,"msg"=>"密碼錯(cuò)誤"]); // die; // } //對(duì)比版本號(hào) $astr = explode('_',$name); $version_num = str_replace(".zip", '',array_pop($astr)); if(!$version_num) { echo json_encode(["status"=>0,"msg"=>"獲取版本號(hào)失敗"]); die; } //對(duì)比 if(!$this->compare_version($version_num)) { echo json_encode(["status"=>0,"msg"=>"不能升級(jí)低版本的"]); 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("上傳升級(jí)包成功!"); $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%"); //執(zhí)行升級(jí) $this->execute_update($package_name); } /** * 升級(jí)操作 * @return [type] [description] */ private function execute_update($package_name) { //解壓 如何使用zip加密壓縮,這里解壓縮的時(shí)候注意要解密 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%"); //升級(jí)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%"); //升級(jí)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更新失敗"); //數(shù)據(jù)庫(kù)回滾 if(file_exists($this->upload_dir.'/'.$package_name."/mysql/mysql_rockback.sql")) { $this->save_log("數(shù)據(jù)庫(kù)回滾"); $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; } } //把解壓的升級(jí)包清除 exec("rm -rf $upload_dir/$package_name "); $this->update_progress("100%"); //更新系統(tǒng)的版本號(hào)了 //更新php的版本號(hào)了(應(yīng)該跟svn/git的版本號(hào)一致) //更新數(shù)據(jù)庫(kù)的版本號(hào)了(應(yīng)該跟svn/git的版本號(hào)一致) echo json_encode(["status"=>1,"msg"=>"升級(jí)成功"]); 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 要確定系統(tǒng)是否已經(jīng)安裝 $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; } //這里還可以對(duì)備份的文件進(jìn)行壓縮 return true; } /** * 數(shù)據(jù)庫(kù)操作 */ 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"=>"數(shù)據(jù)庫(kù)操作OK"]; } /** * 返回系統(tǒng)升級(jí)的進(jìn)度 */ 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 "); } } }
感謝各位的閱讀!看完上述內(nèi)容,你們對(duì)php實(shí)現(xiàn)更新功能的方法大概了解了嗎?希望文章內(nèi)容對(duì)大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。