0

0

php如何实现更新功能

藏色散人

藏色散人

发布时间:2020-09-04 09:36:46

|

4461人浏览过

|

来源于php中文网

原创

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

php如何实现更新功能

推荐:《PHP视频教程

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

思路

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

立即学习PHP免费学习笔记(深入)”;

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

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

I-Shop购物系统
I-Shop购物系统

部分功能简介:商品收藏夹功能热门商品最新商品分级价格功能自选风格打印结算页面内部短信箱商品评论增加上一商品,下一商品功能增强商家提示功能友情链接用户在线统计用户来访统计用户来访信息用户积分功能广告设置用户组分类邮件系统后台实现更新用户数据系统图片设置模板管理CSS风格管理申诉内容过滤功能用户注册过滤特征字符IP库管理及来访限制及管理压缩,恢复,备份数据库功能上传文件管理商品类别管理商品添加/修改/

下载

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 ");
        }
    }
}

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1929

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1263

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1169

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1399

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1229

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号