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.sqlcreate 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 ");
}
}
}
總結
以上是生活随笔為你收集整理的php代码升级更新机制,php如何实现更新功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 请求url 返回json,php
- 下一篇: php将文件夹打包zip文件,php将文