众所周知php无法上传大文件,即使是修改了php.ini文件,最有效的方法就是将文件分片上传再合并
废话不多说,直接上代码
index.html文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<script>
function upload() {
var file = $("#upload_file")[0].files[0]
if (file == undefined) {
layer.msg("请先选择文件");
return false;
}
var loading = layer.load(1, { shade: false });
var name = file.name;
var size = file.size;
var succeed = 0;
var shardSize = 1024 * 1024 * 10;
var shardCount = Math.ceil(size / shardSize);
for (var i = 0; i < shardCount; i++) {
var start = i * shardSize;
var end = Math.min(size, start + shardSize);
var form = new FormData();
form.append("upload_name", name);
form.append("numbers", shardCount);
form.append("number", i + 1);
form.append("data", file.slice(start, end));
$.ajax({
url: "upload.php?action=upload",
type: "POST",
data: form,
async: true,
processData: false,
contentType: false,
success: function (data) {
console.log(data);
var returnData = $.parseJSON(data);
if (returnData.error == 200) {
++succeed;
if (succeed == shardCount) {
$.ajax({
url: "upload.php?action=merge",
type: "POST",
data: { 'numbers': shardCount, 'upload_name': name },
success: function (data) {
var returnData = $.parseJSON(data);
if (returnData.error == 200) {
layer.closeAll();
layer.msg("上传成功");
} else {
layer.closeAll();
layer.msg("其他错误");
}
},
});
}
} else {
layer.open({ content: "上传失败", time: 2 });
}
},
});
}
}
</script>
<body>
<p>
<input type="file" name="" id="upload_file">
</p>
<p>
<button onclick="upload()">上传文件</button>
</p>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://www.layuicdn.com/layui/layui.js"></script>
</html>
upload.php文件
<?php
class upload{
private $path='tmp/';
function uploadFile(){
if(empty($_POST['upload_name'])||empty($_POST['number'])){
die(json_encode(array('error'=>202, 'message'=>'No parameters!')));
}
$name=$_POST['upload_name'];
$nowShardNumber=$_POST['number'];
$fileName = $this->path .$name .$nowShardNumber.".tmp";
$result = move_uploaded_file($_FILES['data']['tmp_name'], $fileName);
if ($result) {
echo json_encode(array('error'=>200, 'message'=>'Upload ok'));
} else {
echo json_encode(array('error'=>201, 'message'=>'Upload error'));
}
}
function merge()
{
if(empty($_POST['upload_name'])||empty($_POST['numbers'])){
die(json_encode(array('error'=>202, 'message'=>'No parameters!')));
}
$fileName = $_POST['upload_name'];
$allShardNumber = $_POST['numbers'];
if(file_exists($fileName)){
unlink($fileName);
}
for($i=1; $i<=$allShardNumber;$i++) {
$shardFile=$this->path.$fileName.$i.'.tmp';
if(file_exists($shardFile)){
file_put_contents($this->path.$fileName,file_get_contents($shardFile), FILE_APPEND);
@unlink($shardFile);
}else{
break;
}
}
echo json_encode(array('error'=>200, 'message'=>'Merge successful!'));
}
}
if(isset($_GET['action'])){
$obj = new upload();
if($_GET['action']==='upload'){
$obj->uploadFile();
}else{
$obj->merge();
}
}else{
echo json_encode(array('error'=>-1, 'message'=>'Error!'));
}
上传一个2.5GB的文件耗时80秒,但是没有完全达到80秒 都看到这了点个赞呗 😃
|