齐博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 "
"; } $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>

在线升级>>
选中升级 文件名称 升级前时间 更新时间 对比差异
正在获取云端数据信息,请稍候...
{{rs.i}} {{rs.showfile}}
{{rs.ctime}}
{{rs.time}} 对比差异
升级说明
  • 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