虛擬主機(jī) 如何上傳大于100M的文件 php網(wǎng)站程序問題
整體邏輯
示例代碼 下載: http://downinfo.myhostadmin.net/upload.zip
只是演示功能,生產(chǎn)環(huán)境需要加強(qiáng)上傳過濾
前端 upload.html<html>
<head>
<meta charset="utf-8">
<title>分片上傳</title>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<body>
<form method="post" id="myForm" enctype="multipart/form-data">
<input type="file" id="file" name="file">
<input type="submit" id="submit" value="上傳">
</form>
<script type="text/javascript">
$('#submit').on('click', function(e) {
// 阻止默認(rèn)表單提交
e.preventDefault();
// 獲取屬性
var myfile = $('#file')[0].files[0];
var ext = myfile.name.split('.').pop();
// 判斷ext是否為視頻
var is_video = ['mp4', 'avi', 'rmvb', 'mkv'].indexOf(ext) > -1;
var fileId = getFileIdentifier(myfile);
// 數(shù)據(jù)切片
var chunks = fileSlice(myfile, is_video);
console.log(chunks)
// 發(fā)送分割數(shù)據(jù)段
sendChunk(fileId, chunks);
})
function getFileIdentifier(file){
// 獲取文件標(biāo)識(shí)符
return file.name
//return file.size + file.name;
}
function fileSlice(file, is_video) {
// 切片不宜過大,過大需要 nginx 以及 php 做相應(yīng)配置
var chunkSize = 1024 * 1024 * 4; //切片大小控制
// 1.初始化數(shù)據(jù)
var totalSize = file.size;
var start = 0;
var end = start + chunkSize;
var chunks = [];
// 2.使用bolb提供的slice方法切片
while (start < totalSize) {
if (is_video) {
console.log('視頻')
var chunk = file.slice(start, end, 'video/mp4');
} else {
console.log('圖片')
var chunk = file.slice(start, end);
}
chunks.push(chunk);
start = end;
end += chunkSize;
}
// 3.返回切片組chunk[]
return chunks;
}
function sendChunk(id, chunks){
// 逐個(gè)提交
// 用于保證ajax發(fā)送完畢
var task = [];
var totalPage=0;
var i=0;
totalPage=chunks.length-1;
var fileExt = id.substr(id.lastIndexOf('.') + 1);
chunks.forEach(function(chunk, index){
var formData = new FormData();
formData.append('file',chunk);
formData.append("fileName",id);
formData.append("totalPage",totalPage);
formData.append("page",index);
$.ajax({
type: "POST",
url: 'upload.php',
data: formData,
contentType: false,
processData: false,
dataType:"json",
async:false,
success: function(data){
// 移除已完成任務(wù)
task.pop();
if (data['status']==200){
console.log(data['downUrl']);
alert(data['downUrl']); //返回上傳文件路徑
}
}
})
task.push('file Working');
})
}
</script>
</body>
</html>
后端 upload.php<?php
if (empty($_POST)) {
$res = ['status' => 500];
echo json_encode($res);
exit;
}
// 創(chuàng)建上傳目錄
if(!is_dir('upload')){
mkdir('upload', 0777);
}
// 創(chuàng)建上傳緩存目錄
if(!is_dir('tmp')){
mkdir('upload', 0777);
}
$fileName = isset($_POST['fileName'])?$_POST['fileName']:'';
$page = isset($_POST['page'])?$_POST['page']:'';
$totalPage = isset($_POST['totalPage'])?$_POST['totalPage']:'';
$fileTmpName = isset($_FILES['file'])?$_FILES['file']['tmp_name']:'';
$status = 206;
$downUrl = '';
if ($fileName== ''|| $page == '' || $totalPage == '' || $fileTmpName == '') {
$res = ['status' => 500];
echo json_encode($res);
exit();
}
// 上傳文件要保存的路徑
$fname = sprintf('./tmp/%s-%s', $fileName, $page);
$data = file_get_contents($fileTmpName);
file_put_contents($fname, $data);
// 整合分片文件
//if ($save) {
if ($totalPage ==$page) {
$uploadFileName = sprintf('./upload/%s%s', time(),$fileName);
$status = 200;
// 合并文件,刪除分片文件
for ($i = 0; $i<=$totalPage; $i++) {
$tmp = sprintf('./tmp/%s-%s', $fileName, $i);
$data = file_get_contents($tmp);
file_put_contents($uploadFileName, $data, FILE_APPEND);
@unlink($tmp);
}
$dir = trim(dirname($_SERVER['PHP_SELF']), '/');
if ($dir!='') {
$dir .= '/';
}
$downUrl = sprintf('%s://%s/%s%s', $_SERVER['REQUEST_SCHEME'], $_SERVER['HTTP_HOST'], $dir,trim($uploadFileName, './'));
$res = ['status' => $status,'downUrl' => $downUrl];
echo json_encode($res);
exit();
}
// 返回上傳狀態(tài)
$res = ['status' => $status,'downUrl' => $downUrl];
echo json_encode($res);
運(yùn)行效果
|
|||||
| >> 相關(guān)文章 | |||||
|
|
|||||