html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/static/layui/css/layui.css" media="all">
<script src="/static/layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
<style type="text/css">
.mask {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #000;
opacity: 0.8;
filter: alpha(Opacity=80);
-moz-opacity: 0.8;
z-index: 999;
display: none;
}
.loading {
position: fixed;
width: 300px;
left: 50%;
margin-left: -150px;
top: 200px;
height: 18px;
border-radius: 10px;
background: #fff;
z-index: 9999;
overflow: hidden;
display: none;
}
</style>
</head>
<body>
<div class="layui-main">
<form class="layui-form" method="post" action="">
<input type="hidden" name="form_submit" value="ok"/>
<div class="layui-form-item">
<label class="layui-form-label">安装包:</label>
<input type="hidden" id="totalPage" value="0"/>
<input type="hidden" id="page" value="1"/>
<input type="hidden" id="status" value="0"/>
<div class="layui-input-block">
<button type="button" class="layui-btn" id="fileUpload"><i class="layui-icon"></i>上传文件</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">安装包名:</label>
<div class="layui-input-block">
<input type="text" name="name" id="name" value="" lay-verify="title" autocomplete="off" readonly="true"
class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">下载地址</label>
<div class="layui-input-block">
<input type="text" name="downUrl" id="downUrl" value="" lay-verify="downUrl" autocomplete="off"
readonly="true" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="" lay-filter="submit">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="mask"></div>
<div class="loading">
<div class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="uploadProgress">
<div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>
</div>
</div>
<!-- 注意:如果你直接复制所有代码到本地,上述js路径需要改成你本地的 -->
<script>
layui.use(['form', 'upload', 'element'], function () {
var form = layui.form;
var upload = layui.upload;
var element = layui.element;
var $ = layui.$;
upload.render({
elem: '#fileUpload',
url: 'upload', //处理上传文件接口
accept: 'file',
auto: false,
acceptMime: '*.*',//允许上传的文件类型
choose: function (obj) {
element.progress('uploadProgress', '0%');//进度条清0
$('.mask').show();//遮罩层
$('.loading').show();//显示进度条
var data = this.data;
var files = obj.pushFile();//选择的文件推入obj
var LENGTH = 500 * 1024; //每片文件大小
obj.preview(function (index, file, result) {
var totalSize = file.size;//文件总大小
var totalPage = Math.ceil(totalSize / LENGTH);//总共上传的片数
$('#totalPage').val(totalPage);
$('#page').val('1');
$('#status').val('1');
var fileName = file.name;//获取文件名
$('#name').val(fileName);
var fileExt = fileName.substr(fileName.lastIndexOf('.') + 1);//获取文件后缀
fileName = fileName.substr(0, fileName.lastIndexOf('.'));//获取不带后缀的文件名
var progressTimer = setInterval(function () {
var totalPage = parseInt($('#totalPage').val());
var page = parseInt($('#page').val());
var status = $('#status').val();
if (parseInt(totalPage) == parseInt(page) && (parseInt(status) == 2 || parseInt(status) == -1)) {
clearInterval(progressTimer);//上传成功或失败停止上传
} else {
//状态为1的时候上传
if (status == 1) {
$('#status').val('0');
data.fileName = fileName;
data.page = page;
data.totalPage = totalPage;
data.fileExt = fileExt;
obj.upload(index, file.slice((page - 1) * LENGTH, page * LENGTH));//从文件中截取进行分片上传
}
}
}, 100);
});
},
done: function (res) {
if (res.status == 1) { //分片上传
var page = parseInt($('#page').val());
var totalPage = parseInt($('#totalPage').val());
element.progress('uploadProgress', Math.ceil(page * 100 / totalPage) + '%');//更新进度条
page = page + 1;//上传下一片
console.log(page);
$('#page').val(page);
$('#status').val('1');
} else if (res.status == 2) { //上传完成
element.progress('uploadProgress', '100%');
$('#status').val('2');
$('#downUrl').val(res.downUrl);
layer.msg('上传成功', {time: 1000, anim: 0}, function () {
$('.mask').hide();//隐藏遮罩层
$('.loading').hide();//隐藏进度条
});
} else { //上传错误
$('#status').val('-1');
element.progress('uploadProgress', '0%');
console.log(!typeof (res.downUrl) == "undefined");
if (typeof (res.downUrl) == "undefined") {
} else {
$('#downUrl').val(res.downUrl);
}
layer.msg("上传失败,请重试", {time: 3000, anim: 0}, function () {
$('.mask').hide();
$('.loading').hide();
});
}
},
error: function () {
$('.mask').hide();
$('.loading').hide();
}
});
});
</script>
</body>
</html>
php代码
public function upload()
{
$status = 1;
//上传文件要保存的路径
$fname = sprintf(public_path() . 'tmp\%s.%s', $_POST['fileName'], $_POST['fileExt']);
$data = file_get_contents($_FILES['file']['tmp_name']);
if ($_POST['page'] == 1) {
file_put_contents($fname, $data);
} else {
//其余文件追加到文件末尾
file_put_contents($fname, $data, FILE_APPEND);
}
//最后一片文件
if ($_POST['totalPage'] == $_POST['page']) {
$status = 2;
$res1 = fen($fname);
}
//返回上传状态
$res = ['status' => $status, 'downUrl' =>isset($res1)?$res1:''];
return json($res);
}
common.php
function fen($file)
{
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
$accessKeyId = "";
$accessKeySecret = "";
// Endpoint以杭州为例,其它Region请按实际情况填写。
$endpoint = "http://oss-cn-shanghai.aliyuncs.com";
// 设置存储空间名称。
$bucket = "";
// 设置文件名称。
$object = rand(1, 9999999999) . '.jpg';
// <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
$uploadFile = $file;
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
//返回uploadId。uploadId是分片上传事件的唯一标识,您可以根据uploadId发起相关的操作,如取消分片上传、查询分片上传等。
$uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
} catch (OssException $e) {
printf(__FUNCTION__ . ": initiateMultipartUpload FAILED
");
printf($e->getMessage() . "
");
return;
}
/*
* 步骤2:上传分片。
*/
$partSize = 10 * 1024 * 1024;
$uploadFileSize = filesize($uploadFile);
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
$fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
$toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
$upOptions = array(
// 上传文件。
$ossClient::OSS_FILE_UPLOAD => $uploadFile,
// 设置分片号。
$ossClient::OSS_PART_NUM => ($i + 1),
// 指定分片上传起始位置。
$ossClient::OSS_SEEK_TO => $fromPos,
// 指定文件长度。
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
// 是否开启MD5校验,true为开启。
$ossClient::OSS_CHECK_MD5 => $isCheckMd5,
);
// 开启MD5校验。
if ($isCheckMd5) {
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
$upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
}
try {
// 上传分片。
$responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
} catch (OssException $e) {
printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED
");
printf($e->getMessage() . "
");
return;
}
}
// $uploadParts是由每个分片的ETag和分片号(PartNumber)组成的数组。
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* 步骤3:完成上传。
*/
try {
$ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
} catch (OssException $e) {
printf(__FUNCTION__ . ": completeMultipartUpload FAILED
");
printf($e->getMessage() . "
");
return;
}
//生成鉴权url
$timeout = 36000000;
$options = array(
OssClient::OSS_PROCESS => "image/resize,m_lfit,h_100,w_100");
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET", $options);
return $signedUrl;
}