当前位置:首页 > 西部数码 > 虚拟主机 > 正文内容

虚拟主机 如何上传大于100M的文件 php网站程序

问题

  1. 虚拟主机上传文件大小限制100m,

  2. 有时会遇到非常大的文件上传,上传过程中耗时非常久,

  3. 可能服务器的限制设置了上传文件尺寸,返回“413 request entity too large”

整体逻辑

  1. 前端:上传文件时,进行文件分片;发起请求时,带上第几次分片上传、总片数。

  2. 后端:按照分片进行文件保存,当上传完最后一片数据时,进行文件合并,并删除分片文


示例代码 下载:  http://downinfo.myhostadmin.net/upload.zip


只是演示功能,生产环境需要加强上传过滤


前端 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) {
    // 阻止默认表单提交
    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);
    // 数据切片
    var chunks = fileSlice(myfile, is_video);
    console.log(chunks)
    // 发送分割数据段
    sendChunk(fileId, chunks);
  })
  function getFileIdentifier(file){
   // 获取文件标识符
   return file.name
   //return file.size + file.name;
  }
  function fileSlice(file, is_video) {
   // 切片不宜过大,过大需要 nginx 以及 php 做相应配置
    var chunkSize = 1024 * 1024 * 4; //切片大小控制
    // 1.初始化数据
    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){
    // 逐个提交
    // 用于保证ajax发送完毕
    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){
          // 移除已完成任务
          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;
}
// 创建上传目录
if(!is_dir('upload')){
  mkdir('upload', 0777);
 }
// 创建上传缓存目录
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();
}

// 返回上传状态
$res = ['status' => $status,'downUrl' => $downUrl];
echo json_encode($res);


运行效果

image.png

“虚拟主机 如何上传大于100M的文件 php网站程序” 的以下内容与本文无关

简单说两句

访客

◎ 不想说话可以不说,说了便要负责!