齐博x1服务器性能太差,调整系统升级每次校验的文件数
系统升级需要校验本地的文件是否被修改过,系统默认每次检验1千个文件,一般来说需要分四到五页来处理,如下图所示。
如果你的服务器性能太差的话,就需要手工把数值调小。把下面的代码复制出来。进入后台数据库管理工具那里执行一下,导入数据库。然后就可以在后台核心设置那里修改数值
INSERT INTO `qb_config` (`id`, `type`, `title`, `c_key`, `c_value`, `form_type`, `options`, `ifsys`, `htmlcode`, `c_descrip`, `list`, `sys_id`) VALUES(0, 1, '系统升级每次核对文件数', 'sys_update_filenum', '10', 'number', '', 1, '', '留空则默认是1000,如果你的空间性能太差,就手工调为50甚至10', 0, 0);
导入数据库后,需要在下面那里做设置,如下图
把数值相应调小,测试看看能否正常升级。
复制下面的代码修改两个文件后,将会实现如下图的效果.
要实现分页检验文件的话,需要修改两个文件.
复制下面的代码替换
\application\admin\controller\Upgrade.php
中的内容
<?php
namespace app\admin\controller;
use app\common\controller\AdminBase;
use app\common\model\Module;
use app\common\model\Plugin;
use app\common\model\Hook_plugin;
use app\common\model\Market as MarketModel;
use app\common\model\Timedtask AS TaskModel;
class Upgrade extends AdminBase
{
public function _initialize(){
parent::_initialize();
if(config('client_upgrade_edition')==''){
config('client_upgrade_edition',RUNTIME_PATH . '/client_upgrade_edition.php');
}
}
public function index()
{
$this->clean_cache();
$array = @include(config('client_upgrade_edition'));
$this->assign('upgrade',$array);
return $this->fetch('index');
}
/**
* 清除相关缓存
*/
protected function clean_cache(){
cache('timed_task',null);
cache('cache_modules_config',null);
cache('cache_plugins_config',null);
cache('hook_plugins',null);
}
/**
* 更新升级日志
* @param string $upgrade_edition
* @return boolean|string
*/
private function writelog($upgrade_edition=''){
$data = $this->request->post();
if($data['m']){
$array = modules_config();
foreach ($array AS $rs){
$de = $data['m'][$rs['keywords']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Module::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['p']){
$array = plugins_config();
foreach ($array AS $rs){
$de = $data['p'][$rs['keywords']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Plugin::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['h']){
$array = cache('hook_plugins');
foreach ($array AS $rs){
$de = $data['h'][$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
Hook_plugin::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
if($data['t']){
$array = cache('timed_task');
foreach ($array AS $rs){
$de = $data['t'][$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
TaskModel::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
$this->upgrade_mark($data['admin_style'],'admin_style');
$this->upgrade_mark($data['index_style'],'index_style');
$this->upgrade_mark($data['member_style'],'member_style');
$this->upgrade_mark($data['qun_style'],'qun_style');
$this->upgrade_mark($data['haibao_style'],'haibao_style');
$this->upgrade_mark($data['model_style'],'model_style');
$this->upgrade_mark($data['packet'],'packet');
$this->clean_cache();
if( file_put_contents(config('client_upgrade_edition'), '<?php return ["md5"=>"'.$upgrade_edition.'","time"=>"'.date('Y-m-d H:i').'",];') ){
return true;
}else{
return '权限不足,日志写入失败';
}
}
/**
* 应用市场,比如风格更新升级日志
* @param array $data
* @param string $type 比如admin_style index_style member_style
*/
private function upgrade_mark($data=[],$type=''){
if($data){
$array = MarketModel::get_list(['type'=>$type]);
foreach ($array AS $rs){
$de = $data[$rs['version_id']];
if($de){
$vs = $de['time']."\t".$de['md5'];
MarketModel::update(['id'=>$rs['id'],'version'=>$vs]);
}
}
}
}
/**
* 更新前,先备份一下文件
* @param string $filename
*/
private function bakfile($filename=''){
$bakpath = RUNTIME_PATH.'bakfile/';
if(!is_dir($bakpath)){
mkdir($bakpath);
}
$new_name = $bakpath.date('Y_m_d-H_i--').str_replace(['/','\\'], '--', $filename);
copy(ROOT_PATH.$filename,$new_name);
}
/**
* 升级数据库
* @param string $filename
*/
private function up_sql($filename=''){
if(preg_match('/\/upgrade\/([\w]+)\.sql$/', $filename)){
//if(preg_match('/^\/application\/common\/upgrade\/([\w]+)\.sql/', $filename)){
into_sql(ROOT_PATH.$filename,true,0);
}
}
/**
* 执行更多复杂的逻辑性的升级
* @param string $filename
*/
private function up_run($filename=''){
if(preg_match('/^\/application\/common\/upgrade\/([\w]+)\.php$/', $filename)){
$classname = "app\\common\\upgrade\\".ucfirst(substr(basename($filename), 0,-4));
}elseif( preg_match('/(application|plugins)\/([\w]+)\/upgrade\/([\w]+)\.php$/',$filename,$array) ){ //实际已包含了上面的
$m_p = $array[1]=='application'?'app':'plugins';
$model = $array[2];
$file = $array[3];
$classname = "$m_p\\$model\\upgrade\\".ucfirst($file);
}else{
return;
}
if( class_exists($classname) && method_exists($classname, 'up') ){
$obj = new $classname;
try {
$obj->up();
} catch(\Exception $e) {
//echo $e;
}
}
}
/**
* 正式执行开始升级,一个一个的文件升级替换
*/
public function sysup($filename='',$upgrade_edition=''){
if($upgrade_edition){ //升级完毕,写入升级信息日志
$result = $this->writelog($upgrade_edition);
if( $result===true ){
return $this->ok_js([],'升级成功');
}else{
return $this->err_js($result);
}
}
list($filename,$id) = explode(',',$filename);
if($filename==''){
return $this->err_js('文件不存在!');
}
$str = $this->get_server_file($filename,$id);
if($str){
$filename = $this->format_filename($filename); //针对模块或插件的升级做替换处理
$this->bakfile($filename);
makepath(dirname(ROOT_PATH.$filename)); //检查并生成目录
if( file_put_contents(ROOT_PATH.$filename, $str) ){
$this->up_sql($filename);
$this->up_run($filename);
return $this->ok_js([],'文件升级成功');
}else{
return $this->err_js('目录权限不足,文件写入失败');
}
}else{
return $this->err_js('获取云端数据失败,请确认服务器DNS是否正常,能否访问外网?');
}
}
/**
* 升级前,可以查看任何一个文件的源代码
* @param string $filename
*/
public function view_file($filename='',$id=0,$oldfile=''){
$str = $this->get_server_file($filename,$id);
if ( preg_match("/(\.jpg|\.png|\.jpeg|\.gif)$/i", $filename) ) {
//header('Content-type:image/'.substr($filename,strripos($filename,'.')+1));echo $str;
if (is_file(ROOT_PATH.$oldfile)) {
echo "->domain().)
";
}
$temp_file = "uploads/images/temp.".substr($filename,strripos($filename,'.')+1);
file_put_contents(PUBLIC_PATH.$temp_file, $str);
echo "
";
exit;
}
$this->assign('new_code',str_replace(['<','>'], ['<','>'], $str));
$this->assign('old_code', str_replace(['<','>'], ['<','>'], file_get_contents(str_replace('//', '/', ROOT_PATH.$oldfile)) ) );
return $this->fetch();
}
/**
* 针对要升级的模块与插件的文件名特别处理, 替换后,// 双斜杠开头的文件就是插件或模块升级的文件
* @param string $filename
* @return string|mixed
*/
protected function format_filename($filename=''){
if(strstr($filename,'/../../')){
$filename = str_replace(['/../../template/','/../../plugin/','/../../hook/'], '/../../', $filename);
$filename = preg_replace('/^\/..\/..\/([\w]+)/','/',$filename);
}
return $filename;
}
/**
* 核对需要升级文件,展示出来给用户挑选哪些不想升级
* 这里的升级文件列表,即有系统的,也有频道插件与风格的
* @param string $upgrade_edition
* @param string $page 分页检验需要升级的文件.一次处理的话,有的服务器可能吃不消
* @return string|mixed
*/
public function check_files($upgrade_edition='',$page=0,$rows=1000){
if ($this->webdb['sys_update_filenum']>0) {
$rows = $this->webdb['sys_update_filenum'];
}
set_time_limit(0); //防止超时
$array = $this->getfile($page);
if(empty($array)){
$str = http_curl("https://x1.php168.com/appstore/upgrade/get_version.html?id=46");
if (!strstr($str,'md5')) {
return $this->err_js('你的服务器无法访问齐博官网,请检查你的服务器DNS是否配置正确,或者是否设置了防火墙不能访问外网');
}
return $this->err_js('获取云端文件列表数据失败,请晚点再偿试');
}
$totalpage = ceil(count($array)/$rows);
if (!$page) {
set_cookie('need_update',0);
return $this->ok_js($totalpage);
}
$data = [];
$min = ($page-1)*$rows;
for($i=$min;$i<$min+$rows;$i++){
$rs = $array[$i];
if (!$rs) {
break;
}
// }
// foreach($array AS $rs){
$showfile = $this->format_filename($rs['file']);
$file = ROOT_PATH.$showfile;
if (is_file($file.'.lock') && file_get_contents($file.'.lock')=='hide') {
continue; //用户不想升级的文件,也不想提示升级
}
$ispic = false;
$change = false;
$md5_size = '';
if (!is_file($file)) {
$change = true;
}elseif( ($md5_size=md5_file($file)) != $rs['md5'] ){
$change = true;
if ( preg_match("/(\.jpg|\.png|\.jpeg|\.gif)$/i", $file) ) {
$ispic = true;
}elseif ( check_bom($file,true) ) {
file_put_contents($file, check_bom($file));
if (md5_file($file)==$rs['md5']) {
$change = false;
}//elseif(preg_match("/(\/|\\\)upgrade(\/|\\\)([\w]+)(\.sql|\.php)$/i", $file)){
//$change = false;
//}
}
}
if($change){
$data[]=[
'file'=>$rs['file'],
'showfile'=>$showfile,
'md5'=>$md5_size,
'id'=>$rs['id'],
'islock'=>(is_file($file.'.lock')||(is_file($file)&&preg_match("/(\/|\\\)upgrade(\/|\\\)([\w]+)(\.sql|\.php)$/i", $file)))?1:0,
'ctime'=>is_file($file)?date('Y-m-d H:i',filemtime($file)):'缺失的文件',
'time'=>date('Y-m-d H:i',$rs['time']),
];
}
}
$array_sql = $array_php = [];
foreach ($data AS $key=>$rs){
if( preg_match("/\/upgrade\/([\w]+\.sql)/i",$rs['file']) ){
unset($data[$key]);
$array_sql[$rs['file']] = $rs;
}elseif( preg_match("/\/upgrade\/([\w]+\.php)/i",$rs['file']) ){
unset($data[$key]);
$array_php[$rs['file']] = $rs;
}
}
ksort($array_php);
ksort($array_sql);
$data = array_values(array_merge($data,$array_sql,$array_php));
$need_update = get_cookie('need_update')+count($data);
set_cookie('need_update',$need_update);
if ($page==$totalpage) {
unlink(RUNTIME_PATH.'updatelist.txt');
}
if($page==$totalpage && $need_update<1){
$upgrade_edition && $reustl = $this->writelog($upgrade_edition);
return $this->err_js($reustl!==true?$reustl:'没有可更新文件');
}else{
return $this->ok_js($data?:[]);
}
}
/**
* 获取云端的某个最新文件
* @param string $filename 升级的文件名
* @param number $id 对应云端的插件ID
* @return string|mixed
*/
protected function get_server_file($filename='',$id=0){
@set_time_limit(600); //防止超时
$str = http_curl('https://x1.php168.com/appstore/upgrade/make_client_file.html?filename='.$filename.'&id='.$id.'&appkey='.urlencode($this->webdb['mymd5']).'&domain='.urlencode($this->request->domain()));
if(substr($str,0,2)=='QB'){ //文件核对,防止网络故障,抓取一些出错信息
$str = substr($str,2);
}else{
$str='';
}
return $str;
}
/**
* 获取云端的最新文件列表
* @return string|mixed
*/
protected function getfile($page=0){
if (!$page) {
$str = http_curl('https://x1.php168.com/appstore/upgrade/get_list_file.html?typeid='.$this->webdb['typeid'].'&appkey='.urlencode($this->webdb['mymd5']).'&domain='.urlencode($this->request->domain()),['app_edition'=>fun('upgrade@local_edition')]);
file_put_contents(RUNTIME_PATH.'updatelist.txt', $str);
}else{
$str = file_get_contents(RUNTIME_PATH.'updatelist.txt');
}
return $str ? json_decode($str,true) : '';
}
}
?>
复制下面的代码替换
\template\admin_style\default\admin\upgrade\index.htm
中的内容
{extend name="index:layout" /}
{block name="menu"}{/block}
{block name="content"}
<script src="__STATIC__/js/core/vue.js"></script>
<script type="text/javascript">
</script>
升级说明
- 1、你可以选择哪些文件不升级,不过你最好是在程序目录,把不想升级的文件,做个标志,比如“index.htm”不想升级,就在对应的目录创建一个文件“index.htm.lock”,这样每次升级,文件就处于非选中状态,而不会升级。
- 2、如果网络故障,一次升级不成功,可反复升级
- 3、如果因为升级文件被替换了,请进目录/runtime/bakfile/找回来
- 4、系统默认每次校验文件数是1千个,如果你的空间性能太差的话,请点击查看教程进行设置
<script src="__STATIC__/layui/layui.js"></script>
<script type="text/javascript">
var element;
$(function(){
layui.use('element', function(){
element = layui.element;
})
//element.progress('progressId', i+'%');
})
</script>
<script language=JavaScript>
var upgrade_edition = '';
var upgrade_data = {};
//检查版本更新
function check_upgrade(){
var now_edition = "{$upgrade.md5}";
$.post("https://x1.php168.com/appstore/upgrade/get_edition.html?typeid={$webdb.typeid}&"+Math.random(),{
app_edition:"{:fun('upgrade@local_edition')}",
sys_edition:now_edition,
domin:'{:request()->domain()}',
appkey:'{$webdb.mymd5}'
}).success( function(res){
if(res.code==0){
upgrade_data = res.data;
if(res.data.md5!=now_edition||typeof(res.data.upgrade_msg) != "undefined"){
if(typeof(res.data.time) == "undefined"){
return ;
}
upgrade_edition = res.data.md5;
var msg = typeof(res.data.upgrade_msg) != "undefined" ? res.data.upgrade_msg : '你的系统需要升级
云端更新日期:'+res.data.time;
$(".upgrade_msg").html(msg);
layer.confirm(msg, {
btn : [ '查看需要升级的文件', '晚点再升级' ]
}, function(index) {
down_file_list();
});
}else{
$(".upgrade_msg").html('已经是最新了,无须升级');
}
}else{
layer.alert(res.msg,{time:5500});
}
}).fail(function (res) {
//layer.alert('网络故障,请晚点再偿试升级!!');
//layer.closeAll();
layer.open({title: '网络故障,请晚点再偿试升级!!',area:['90%','90%'],content: res.responseText});
});
}
check_upgrade();
var app_ids = {};
var vues = new Vue({
el: '#upgradeTR',
data: {
listdb: [],
},
watch:{
listdb: function() {
this.$nextTick(function(){ //数据渲染完毕才执行
var time = 100;
$("input[data-islock=0]:not(:checked)").each(function(){
time += 200;
var that = $(this);
var url = "https://x1.php168.com/appstore/upgrade/check_md5.html?path="+that.attr('data-showfile')+"&md5="+that.attr('data-md5');
setTimeout(function(){
$.get(url,function(res){
if(res.code==0){
that.attr('checked',true);
}
});
},time);
});
var times = 500;
$(".listfile").each(function(){
var that = $(this);
if(that.attr("data-id")){
var id = that.attr("data-id");
if(app_ids[id]==undefined){
app_ids[id] = {};
times += 500;
setTimeout(function(){
$.get("https://x1.php168.com/appstore/wxapp.show/index.html?id="+id,function(res){
if(res.code==0){
//app_ids[id] = res.data;
$(".listfile[data-id="+id+"]").append(" "+res.data.title+"");
}
});
},times);
}
}
});
$(".up_btn").show();
layer.alert('需要升级的文件列表如下,你可以有选择性的升级');
});
}
},
methods: {
add_data:function(array){
$("#contents").remove();
array.forEach((rs,i)=>{
rs.i = i+1;
this.listdb.push(rs);
});
}
}
});
var need_update_file = [];
function check_need_update(totalpage,page){
if(page==1)layer.load(1,{shade: [0.7, '#393D49']}, {shadeClose: true}); //0代表加载的风格,支持0-2
layer.msg('正在核对需要升级的文件, '+page+' / '+totalpage+' 页,
需要一点时间,请耐心等候!',{icon:1,time:30000, shift: 1});
$.post("{:urls('check_files')}?upgrade_edition="+upgrade_edition+"&page="+page,upgrade_data,function(res){
if(res.code==0){
res.data.forEach((rs)=>{
need_update_file.push(rs);
});
if(page'+
' '+
''+rs.showfile+''+
''+rs.ctime+''+
''+rs.time+''+
'查看'+
'';
});
document.getElementById('contents').outerHTML=str;
*/
}else{
layer.alert(res.msg,{time:5500});
}
}).fail(function (res) {
layer.closeAll();
//layer.alert('通信失败,可能你的后台权限不足'); )
var parsedJson = $.parseJSON(res.responseText.substr(res.responseText.indexOf('{'))); //用户程序中有UTF8 +BOM文件导致的
if( typeof(parsedJson) == 'object' && parsedJson.code==0){
//vues.add_data(parsedJson.data);
check_need_update(res.data,1);
/*
var str = '';
parsedJson.data.forEach(function(rs){
var ck = rs.islock?" onclick='layer.alert(\"当前文件已锁定,你确认要升级吗?\")' ":' checked ';
var style = rs.islock?" class='locktr' ":' ';
str +=''+
' '+
''+rs.showfile+''+
''+rs.ctime+''+
''+rs.time+''+
'查看'+
'';
});
document.getElementById('contents').outerHTML=str;
*/
//$(".up_btn").show();
//layer.alert('需要升级的文件列表如下,你可以有选择性的升级
特别提醒:你的系统中有错误的UTF8 +BOM 代码文件,一般情况是新装的风格导致的,请仔细排查!');
return ;
}else if( typeof(parsedJson) == 'object' && parsedJson.code==1){
layer.alert(parsedJson.msg+"
特别提醒:你的系统中有错误的UTF8 +BOM 代码文件,一般情况是新装的风格导致的,请仔细排查!",{time:5500});
return ;
}
layer.confirm('通信失败,你是否要新开窗口查看一下详情?'+JSON.stringify(res), {
btn : [ '查看详情', '取消' ]
}, function(index) {
window.open("{:urls('check_files')}?upgrade_edition="+upgrade_edition);
});
});
}
//开始升级文件
function sys_upgrade(){
$(".up_files input[type='checkbox']").each(function(i){
if($(this).is(':checked')==true){
ckfile_num++;
}
});
layer.alert('正在升级文件,请耐心稍候...');
var index = layer.load(1,{shade: [0.7, '#393D49']}, {shadeClose: true}); //0代表加载的风格,支持0-2
$(".progress_warp").show();
var time = 0;
$(".up_files input[type='checkbox']").each(function(i){
if($(this).is(':checked')==true){
var file_name = $(this).val();
var obj = $(this).parent().next();
if( file_name.indexOf('/upgrade/')>0 ){
time += 3000;
}else{
time += 500;
}
setTimeout(function(){
upgrade_file(file_name,obj);
},time);
}
});
}
//全部升级完毕
function end_up(){
layer.msg('全部文件升级成功');
$.post("{:urls('sysup')}?upgrade_edition="+upgrade_edition,upgrade_data).success(function(res){
if(res.code==0){
layer.alert('本次升级完毕,'+ok_num+'个文件升级成功!');
}else{
layer.alert('升级信息写入失败');
}
}).fail(function (res) {
layer.open({title: '网络故障,请晚点再偿试升级!!',area:['90%','90%'],content: res.responseText});
});
}
var ckfile_num = 0; //选中的升级文件个数
var ok_num = 0; //成功升级文件个数
//一个一个的文件升级
function upgrade_file(filename,obj){
$.post("{:urls('sysup')}?filename="+filename,upgrade_data).success(function(res){
if(res.code==0){
//layer.msg('文件:'+filename+' 升级成功');
var str = obj.html()+' 升级成功';
obj.html(str);
ok_num++;
if(ok_num==ckfile_num){ //全部升级完毕
layer.closeAll();
end_up();
$(".progress_warp").hide();
}
element.progress('progressId', parseInt(ok_num*100/ckfile_num)+'%'); //升级进度
}else{
//layer.msg('文件:'+filename+' 升级失败:'+ res.msg,{time:2500});
var str = obj.html()+' 升级失败:'+res.msg+'';
obj.html(str);
}
}).fail(function (res) {
//layer.alert('通信失败,可能你的后台权限不足');
layer.open({title: '网络故障,请晚点再偿试升级!!',area:['90%','90%'],content: res.responseText});
});
}
function CheckAll(form){
for (var i=0;i