首页 智能穿戴

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传

分类:智能穿戴
字数: (4732)
阅读: (4877)
内容摘要:Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传,

随着短视频、在线教育等行业的蓬勃发展,大视频文件的上传需求日益增长。传统的直接上传方式,不仅耗时漫长,而且容易因网络波动导致上传失败。针对这一痛点,本文将深入探讨如何利用 Layui 前端框架和 PHP 后端技术,构建一个高效、稳定的大视频分片上传方案

问题场景重现:传统上传的困境

设想一个场景:用户需要上传一个 2GB 的高清视频,通过传统的 HTTP POST 方式直接上传到服务器。在高并发场景下,服务器的带宽资源可能被瞬间耗尽,导致其他用户的访问请求受阻。同时,由于网络环境的复杂性,上传过程中极易出现连接中断的情况,用户不得不重新上传,体验极差。而且这种上传方式对服务器的压力很大,容易出现502错误,如果再使用宝塔面板的话,很容易出现服务器假死。

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传

底层原理深度剖析:分片上传与断点续传

分片上传的核心思想是将一个大文件分割成多个较小的文件块(chunk),然后并行上传这些文件块。这样既可以有效利用带宽资源,降低服务器压力,还可以实现断点续传功能。即使某个文件块上传失败,只需重新上传该文件块即可,无需从头开始。

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传

断点续传则是在分片上传的基础上,记录已上传的文件块信息。当上传中断后,客户端可以根据记录,从上次中断的位置继续上传。通常,我们可以使用 Redis 缓存或者数据库来存储已上传的文件块信息,避免重复上传。

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传

Layui 前端实现:文件切片与进度展示

Layui 作为一款轻量级的前端框架,提供了丰富的 UI 组件和便捷的 API,非常适合用于构建分片上传功能。

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传
<div class="layui-upload">
  <button type="button" class="layui-btn layui-btn-normal" id="selectFile">选择文件</button>
  <div class="layui-progress layui-progress-big" lay-showpercent="yes" id="uploadProgress">
    <div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
  </div>
</div>
layui.use(['upload', 'element'], function(){
  var upload = layui.upload;
  var element = layui.element;
  
  upload.render({
    elem: '#selectFile',
    url: '/upload.php', // 后端上传接口
    accept: 'video', // 允许上传视频
    size: 1024 * 1024 * 1024 * 2, // 最大允许上传2GB
    auto: false, // 不自动上传
    bindAction: '#startUpload', // 绑定开始上传按钮
    choose: function(obj){ // 选择文件后的回调
      obj.preview(function(index, file, result){
        // 文件预览
        console.log(file);
        var fileSize = file.size;
        var chunkSize = 1024 * 1024; // 1MB 一个分片
        var chunkCount = Math.ceil(fileSize / chunkSize);

        // 创建 FormData 对象,用于存储分片数据
        var formData = new FormData();
        formData.append('file', file);
        formData.append('chunkSize', chunkSize);
        formData.append('chunkCount', chunkCount);

        // 循环上传分片
        for (var i = 0; i < chunkCount; i++) {
          var start = i * chunkSize;
          var end = Math.min(fileSize, start + chunkSize);
          var chunk = file.slice(start, end);

          var chunkFormData = new FormData();
          chunkFormData.append('chunk', chunk); // 分片数据
          chunkFormData.append('chunkIndex', i); // 分片索引
          chunkFormData.append('filename', file.name); // 文件名
          
          // 发送 AJAX 请求上传分片
          $.ajax({
            url: '/upload.php',
            type: 'POST',
            data: chunkFormData,
            contentType: false, // 必须设置
            processData: false, // 必须设置
            async: false, // 同步上传,确保分片顺序
            success: function(res){
              console.log('分片 ' + i + ' 上传成功');
              // 更新上传进度
              var percent = Math.round(((i + 1) / chunkCount) * 100) + '%';
              element.progress('uploadProgress', percent);
            },
            error: function(err){
              console.error('分片 ' + i + ' 上传失败', err);
            }
          });
        }

        console.log('文件上传完成');
      });
    }
  });
});

PHP 后端实现:分片接收与合并

PHP 后端负责接收前端上传的文件分片,并将它们按照正确的顺序合并成完整的文件。为了提高性能,可以使用 Nginx 作为反向代理服务器,并配置合理的并发连接数。

<?php
$target_dir = "uploads/";
$filename = $_POST['filename'];
$chunkIndex = $_POST['chunkIndex'];

$target_file = $target_dir . $filename . ".part" . $chunkIndex; // 分片临时文件路径

if (move_uploaded_file($_FILES["chunk"]["tmp_name"], $target_file)) {
  echo "分片上传成功";
  // 检查是否所有分片都已上传
  $chunkCount = $_POST['chunkCount'];
  $allChunksUploaded = true;
  for ($i = 0; $i < $chunkCount; $i++) {
    if (!file_exists($target_dir . $filename . ".part" . $i)) {
      $allChunksUploaded = false;
      break;
    }
  }

  if ($allChunksUploaded) {
    // 合并分片
    $final_file = $target_dir . $filename;
    $output_file = fopen($final_file, 'wb');
    for ($i = 0; $i < $chunkCount; $i++) {
      $chunk_file = $target_dir . $filename . ".part" . $i;
      $chunk_content = file_get_contents($chunk_file);
      fwrite($output_file, $chunk_content);
      unlink($chunk_file); // 删除分片临时文件
    }
    fclose($output_file);
    echo "<br>文件合并完成";
  }

} else {
  echo "分片上传失败";
}
?>

实战避坑经验总结

  1. 分片大小的选择: 分片大小应根据网络环境和服务器性能进行调整。过小的分片会增加请求次数,降低上传效率;过大的分片则可能因网络波动导致上传失败。
  2. 错误处理: 在前端和后端都需要完善的错误处理机制。例如,前端需要捕获 AJAX 请求的错误,并提示用户重新上传;后端需要验证文件类型、大小等信息,防止恶意上传。
  3. 并发控制: 在高并发场景下,需要对上传请求进行并发控制,防止服务器负载过高。可以使用队列或者令牌桶算法来限制并发连接数。
  4. 安全性: 务必对上传的文件进行安全检查,防止上传恶意文件。可以使用病毒扫描工具或者自定义脚本来检测文件内容。
  5. 断点续传实现: 为了实现断点续传,需要在前端记录已上传的分片信息,并在上传中断后,将这些信息传递给后端。后端需要根据这些信息,跳过已上传的分片,继续上传未上传的分片。
  6. Nginx配置: 如果使用 Nginx 作为反向代理,需要配置 client_max_body_size 参数,允许上传大文件。同时,可以开启 Gzip 压缩,减少网络传输量。

掌握了这些技巧,相信你也能轻松实现基于 Layui 前端和 PHP 后端的大视频分片上传方案。使用这种方案,配合宝塔面板和良好的服务器配置,能够显著提升用户体验和服务器性能。

Layui 前端与 PHP 后端协同:轻松实现大视频分片上传与断点续传

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea1.store/blog/435437.SHTML

本文最后 发布于2026-03-31 10:36:11,已经过了27天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 番茄炒蛋 6 天前
    实战避坑经验总结很实用,避免了很多弯路,点赞!
  • 格子衫青年 14 小时前
    写的真不错,解决了我的一个大问题,之前一直困扰于大文件上传,看来分片上传是最佳方案!