1、功能背景
- 配置管理系统中,需通过web端实现设备的在线升级,此功能需在web页面实现升级包的上传。
- 由于php.ini中的默认上传文件大小为2M,当php代码实现文件上传功能时,超过2M大小的文件无法直接上传,需调整php.ini中相关参数。
- 修改php.ini中相关参数:
file_uploads = On
upload_max_filesize = 20M
post_max_size = 20M - 当修改完参数重启系统后,上传文件仍是失效,无法实现。分析LAMP环境在设备上移植安装时,可能存在多份php.ini配置文件。需将多份配置文件中相关参数全部修改保存并重启才能生效。
- 考虑到移植环境的复杂性及限制性,在线升级功能引入jquery.fcup.js插件,将大文件分片,实现升级包的上传及设备在线升级。
2、jquery.fcup.js
<script src="tpl/js/js/jquery.min.js"></script>
<script src="tpl/js/js/jquery.fcup.js"></script>
<script>
$.fcup({
updom: '.fcup',//上传控件的位置dom
//upid: 'upid',//上传的文件表单id,有默认
shardsize: '2',//切片大小,(单次上传最大值)单位M,默认2M
upmaxsize : '1024',//上传文件大小,单位M,不设置不限制
upstr: '文件上传',//按钮文字
uploading: '上传中...',//上传中的提示文字
upfinished: '长传完成',//上传完成后的提示文字
upurl: 'update.php',//文件上传接口 node接口:http://127.0.0.1:8888/upload
uptype: '<?php echo $file_type?>',//上传类型检测,用,号分割
errmaxup: '长传文件过大',//检测文件是否超出设置上传大小
errtype: '请重新上传<?php echo $file_type?>类型文件',//不支持类型的提示文字
//接口返回结果回调
upcallback : function(result){
//console.log(result);
var result=eval('('+result+')');
//alert(result.msg);
if (result.err != '0'){
$.fcupStop('please upload again!');//终止运行,并且在按钮上显示内容
alert(result.msg);
}else{
if(parseInt(result.index)>=parseInt(result.total)){//上传文件完成
alert(result.msg);
}
}
}
});
</script>
3、结合jquery.fcup.js的业务逻辑,可实现分片大小及文件最大限制的动态限制
$file_type='zip';//上传压缩包类型
$max_size=15;//允许上传大小,单位 M
define(is_max_file,true);//是否大文件上传
$min_size=0.1;//切片文件大小,单位M
if(!is_max_file){
$min_size=$max_size;
}
function alert($arr){
if(!(isset($arr['index'])&&isset($res['total']))){
if(!is_max_file){
$arr['index']=$res['total']=1;
}
}
if(is_max_file){
$str='{';
foreach($arr as $key=>$val){
if($str!='{'){
$str.=',';
}
$str.='"'.$key.'":'.'"'.$val.'"';
}
$str.='}';
echo $str;
exit;
}
echo '<script>alert("'.$arr['msg'].$arr['err'].'");</script>';
if($arr['err']==0){
echo '<script>location.href=location.href;</script>';
}else{
echo '<script>history.go(-1);</script>';
}
exit;
}
$post=strtolower($_SERVER['REQUEST_METHOD']);
if($post=='post'){
$file='file';
foreach( $_FILES as $key=>$val){
$file=$key;
}
$file_name=isset($_POST['file_name']) ? $_POST['file_name'] :''; //大文件名称
$file_name =is_max_file?$file_name:$_FILES[$file]['name'];
$md5 = isset($_POST['file_md5']) ? $_POST['file_md5'] : 0; //文件的md5值
$size = isset($_POST['file_size']) ? $_POST['file_size'] : null; //文件大小
//$file_name=$_FILES[$file]['name'];
if (!empty($_FILES[$file]['error'])) {
switch($_FILES[$file]['error']){
case '1':
$error = '超过php.ini允许的大小。';
break;
case '2':
$error = '超过表单允许的大小。';
break;
case '3':
$error = '文件只有部分被上传。';
break;
case '4':
$error = '请选择图片。';
break;
case '6':
$error = '找不到临时目录。';
break;
case '7':
$error = '写文件到硬盘出错。';
break;
case '8':
$error = 'File upload stopped by extension。';
break;
case '9':
$error = '上传文件错误。';
break;
case '999':
default:
$error = '未知错误。';
}
$res['msg']=$error;
$res['err']=-1;
alert($res);
}
//服务器上临时文件名
$tmp_name = $_FILES[$file]['tmp_name'];
if (!file_exists($tmp_name)) {
$res['msg']="上传文件失败";
$res['err']=-2;
alert($res);
}
//判断升级文件是否存在
if(file_exists("/var/www/update/")){
$res['msg']="正在升级中!请稍后...";
$res['err']=-3;
alert($res);
}
//判断升级文件名是否正确
if($file_name != "update.zip"){
$res['msg']="上传升级包文件名错误,请重新上传!";
$res['err']=-9;
alert($res);
}
$temp_arr = explode(".", $file_name);
$file_ext = array_pop($temp_arr);
$file_ext = trim($file_ext);
$file_ext = strtolower($file_ext);
//var_dump($temp_arr);
if($file_ext!=$file_type){
$res['msg']="文件类型错误,请上传".$file_type."压缩包";
$res['err']=-1;
alert($res);
}
//文件大小检查文件大小
$file_size = $size;
if ($file_size > $max_size*1024*1024) {
$res['msg']="上传文件不能超过".$max_size."M";
$res['err']=-1;
alert($res);
}
//$save_path=dirname(__Dir__);
$save_path=dirname(__Dir__).'/'. 'update.'.$file_type;//上传路径
// $oldfile_path = iconv($save_path . 'web.zip','utf-8','GBK');
$res['total']=isset($_POST['file_total']) ? $_POST['file_total']:0; //总片数
$res['index']=isset($_POST['file_index']) ? $_POST['file_index']:0; //当前片数
if($res['index']<=1){
if (file_exists($save_path)) {
@unlink($save_path);
}
}//删除重传
$content = file_get_contents($tmp_name);
if (!file_put_contents($save_path, $content, FILE_APPEND)) {
@unlink($tmp_name);
$res['msg']="上传文件失败";
$res['err']=-1;
alert($res);
}
@unlink($tmp_name);
$res['msg']="上传文件完成!";
$res['err']=0;
alert($res);
}//post结束
通过上述业务逻辑,可引用fcup.js并将其中的参数修改如下:
shardsize: ‘<?php echo $min_size?>’,//切片大小,(单次上传最大值)单位M,默认2M
upmaxsize : ‘<?php echo $max_size?>’,//上传文件大小,单位M,不设置不限制
4、升级包文件上传完成后,采用ajax实现升级包的完整性校验
- 修改fcup.js的逻辑
$.fcup({
updom: '.fcup',//上传控件的位置dom
//upid: 'upid',//上传的文件表单id,有默认
shardsize: '<?php echo $min_size?>',//切片大小,(单次上传最大值)单位M,默认2M
upmaxsize : '<?php echo $max_size?>',//上传文件大小,单位M,不设置不限制
upstr: '上传升级包',//按钮文字
uploading: '上传中...',//上传中的提示文字
upfinished: '上传完成',//上传完成后的提示文字
upurl: 'update.php',//文件上传接口 node接口:http://127.0.0.1:8888/upload
uptype: '<?php echo $file_type?>',//上传类型检测,用,号分割
errmaxup: '上传文件过大',//检测文件是否超出设置上传大小
errtype: '请上传<?php echo $file_type?>文件',//不支持类型的提示文字
//接口返回结果回调
upcallback : function(result){
// alert(result);
//console.log(result);
var result=eval('('+result+')');
//alert(result.msg);
if (result.err != '0'){
$.fcupStop('重新上传');//终止运行,并且在按钮上显示内容
alert(result.msg);
}else{
if(parseInt(result.index)>=parseInt(result.total)){//上传文件完成
//alert(result.msg);
document.getElementById("checkstate").style.display = "block";
document.getElementById("checkstate").innerHTML = "升级包校验中请稍候......";
document.getElementById("checkstate").style.color = "blue";
updateGet();
//loadProgress();
//setInterval(loadProgress,1000);
}
}
}
});
- 前端逻辑js
function createXmlRequest()
{
if(window.ActiveXObject) {
var xmlHttps=["Microsoft.XMLHTTP","MSXML2.XMLHttp.5.0","MSXML2.XMLHttp4.0", "MSXML2.XMLHttp3.0","MSXML2.XMLHttp"];
try {
for(var i=0;i<xmlHttps.length;i++) {
var xmlHttp=new ActiveXObject(xmlHttps[i]);
return xmlHttp;
}
} catch (error) { }
} else {
var xmlHttp=new XMLHttpRequest();
return xmlHttp;
}
}
function ajaxget(xmlHttp, url) {
xmlHttp.open("GET", url, true);//true为异步请求
xmlHttp.setRequestHeader("If-Modified-Since", "0");//头部字段的名称和信息
xmlHttp.send("");//send方法中的参数表示需要请求发送的数据
}
var xmlget1;
//对升级包进行解压缩并完整性校验,校验成功则下发升级命令至网关程序
function updateGet(){
var url = "updateresult.php";
xmlget1 = createXmlRequest();
xmlget1.onreadystatechange = backUpdate;
ajaxget(xmlget1, url);
}
function backUpdate(){
if (xmlget1.readyState == 4) {
if(xmlget1.status == 200){
var res = xmlget1.responseText;
if(res==1){
//alert("升级包完整性校验成功!");
document.getElementById("checkstate").innerHTML = "升级包校验成功!";
document.getElementById("checkstate").style.color = "green";
loadProgress();
}else{
//alert("升级包完整性校验失败!");
document.getElementById("checkstate").innerHTML = "升级包校验失败!请重新上传!";
document.getElementById("checkstate").style.color = "red";
}
}
}
}
- 后端校验updateresult.php
$resflag1 = 1;
$cmd = "unzip /var/www/update.zip -d /var/www/";
shell_exec($cmd);
if(file_exists("/var/www/update/filemd5.txt")){
$oldmd51 = trim(@file_get_contents("/var/www/update/filemd5.txt"));
$newmd51 = md5_file("/var/www/update/updated.zip");
if($oldmd51 != $newmd51){
$resflag1 = 0;
}
}
if($resflag1){//校验成功
//此处为具体的升级逻辑操作,如解压具体的升级包等
echo "1";
}else{//校验失败
$cmd = "rm /var/www/update.zip";
shell_exec($cmd);
$cmd = "rm -r /var/www/update";
shell_exec($cmd);
echo "0";
}
最后推荐一个公众号,一枚IT技术人成长路上关于生活和职场的思考,欢迎书友们前来交流和分享心得
福利~ 福利~ 福利~ 1块钱一次帮下优快云资料
添加微信,备注下载资料~所需下载优快云资料链接可通过微信发送。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200907091119151.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZxX2ZseQ==,size_16,color_FFFFFF,t_70#pic_center