问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

PHP项目,如何做到自动更新数据?

发布网友 发布时间:2022-04-28 04:03

我来回答

5个回答

懂视网 时间:2022-04-28 08:24

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."
";
 if($action == "update")
 {
  exec(" echo '".$msg."' >> $this->update_log ");
 }else
 {
  exec(" echo '".$msg."' >> $this->return_log ");
 }
 }
}

热心网友 时间:2022-04-28 05:32

建议用服务器跑定时任务,如果用ajax去判断,只能是有人访问你的页面才可以实现,不访问页面的话,永远都变不了,linux 中用 cron,window 用计划任务

热心网友 时间:2022-04-28 06:50

AJAX异步定时,1秒一次

热心网友 时间:2022-04-28 08:25

借助jQuery,每秒执行一次,更新数据库字段追问可不可以这个简单的字段代码?

热心网友 时间:2022-04-28 10:16

是每一个时刻 对应一个值吗?追问额具体情况是,我有一个state字段,还有一个截止时间字段,我需要随时判断截止时间是否已经小于现在的时间,如果是的话,那就将state字段值设置为已过期,这样子怎么做啊

追答

这个我知道两种做法,一个是在前台:用js脚本做;另一个是在后台 做判断,这个如果不推荐,对服务器压力太大。

js: 

        

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
求大学生谈恋爱的各种弊端 大学生恋爱的利大于弊吗? 大学生谈恋爱的弊处 dnf现在站街16000的物攻 增加100物攻能张多少 家里养的蚕宝宝是要蜕皮了吗 富贵包硬和软的区别 【已完成】为什么腋窝突然有异味? 女生为什么有狐臭症状? 为什么会狐臭 万视宝这个牌子是做什么的?有人了解嘛? php如何获得系统当前日期的前三天 PHP怎样获得最近一个周一和上周一的日期? ajax+php 如何获取当前时间 php 获取当前时间 php中如何获取最近六个月每个月的起始时间和结束时间 用php怎么获取当前的前一天和后一天的日期啊? php 如何判断下一个月 几号 如何用php获取当前日期的7天内的时间 怎么用PHP获得当前月的1号是从星期几开始的呢???急急急!!! 请问哪位高手,如何用php获取当前日期的7天内的时间,比如今天是5号,我想获取5号前7天的日期,怎么获取? php中使用mktime() 如何获取上一月昨天的时间,今天的时间,明天的时间; php时间 转换/Date(1435646188067+0800)/成2015-6-30 10:1:29这样的样子 php 如何计算时间 显示服务器时间的php代码。 php如何实现服务器时间自动跳动 Golang中国的markdown转HTML怎么实现 有没有把Markdown代码转成HTML的PHP函数或JsScript函数 markdown怎么转换html markdown转html如何使用php实现? 如何将Markdown文件转换成HTML? php如何实现前台数据自动更新 PHP 如何让时间自动更新 PHP用复选框和下拉菜单如何实现批量更新 PHP中如何实时刷新并且更替显示的数据 如何使用php实现时间时时更新 PHP网页如何自动更新 php网站如何更新缓存 php 实现每五分钟定时进行update更新 怎么做 自动更新 PHP按钮实现数据更新功能? php 怎么让一个页面中的一个内容自动更新? 在PHP中怎么实现新增数据,刷新表格,而不刷新整个页面。 php怎么实现数据在后台的自动更新? thinkphp怎么写更新缓存功能 itunes未能连接到这部iphone,因为发生了未知错误(0xE8000065) iphone与itunes连接时发生未知错误(0xE8000065) itunes无法连接iphone连接时发生未知错误(0xE8000065),求助!! itunes无法连接iphone发生未知错误0xe80000015 求助:itunes无法连接到这部iphone.未知错误[0xE8000065][其实是ipad啊] itunes无法连接iphone连接时发生未知错误(0xE8000065),系统XP ipod touch 1代 强行关机关不了,连接iTunes一直显示无法连接,出现错误0XE8000065