PHP中如何使用TUS协议来实现大文件的断点续传

PHP中如何使用TUS协议来实现大文件的断点续传

你是否曾经为大文件上传而苦恼?如果文件上传的过程中,因为某种原因中断了,是否可以从中断的位置继续上传,而不用重新上传整个文件?如果你有这样的困惑,那么请继续阅读下面的内容。

在现代网站应用中,上传文件是非常常见的。在任何语言中,通过使用一些工具,都可以实现文件上传的功能。但是,如果处理大文件上传的需求,还是有点麻烦的。

假如你此时正在上传一个很大的文件,大约一个小时过去了,进度是 90%。突然断网了或者浏览器崩溃了,上传的程序退出,你要再全部重新来过。真的很不爽,对不对?还有更让人郁闷的是,如果你的网速很慢,那么,无论你重来多少次,你都不可能上传成功。

PHP中如何使用TUS协议来实现大文件的断点续传

在 PHP 中,我们可以尝试利用 tus 协议的断点续传功能来解决这个问题。

什么是 tus?

Tus 是一个基于 HTTP 的 文件断点续传开放协议。 断点续传的意思是不管是用户自行中断,还是由于网络等原因的意外中断,都可以从中断的地方继续上传,而不用重新开始。

为什么用 tus?

引用 Vimeo 的博客:

使用这种方式上传的另一个好处是,你可以在笔记本上开始上传文件,然后又转到手机或者其他设备继续上传同一个文件,这可以极大地提升用户体验。

PHP中如何使用TUS协议来实现大文件的断点续传

图片: Tus 大致的工作流程

开始

第一步,加载依赖。

$ composer require ankitpokhrel/tus-php

tus-php 是用于 tus 断点续传协议 v1.0.0 的一个的纯 PHP 框架,完美实现了 服务端与客户端的交互 。

创建一个处理请求的服务端

你可以像下面这样创建一个服务端.

// server.php

$server   = new \\TusPhp\\Tus\\Server('redis');
$response = $server->serve();

$response->send();

exit(0); // 退出当前 PHP 进程

你需要配置你的服务器以便能对特定的终端进行响应. 如果使用 Nginx 的话你可以像下面这样配置:

# nginx.conf

location /files {
    try_files $uri $uri/ /path/to/server.php?$query_string;
}

假设我们服务端的 URL 是 http://server.tus.local. 因此, 基于我们上面的 Nginx 配置,我们可以通过 http://server.tus.local/files. 来访问到我们的 tus 终端.

基于 RESTful 风格的端点配置:

# 获取有关服务器目前配置的信息\\
OPTIONS /files

# 检查上传的文件是否合法\\
HEAD /files/{upload-key}

# 创建\\
POST /files

# 修改\\
PATCH /files/{upload-key}

# 删除\\
DELETE /files/{upload-key}

查看 协议细则 获取更多关于路由的信息。

使用 tus-php 客户端处理上传

服务器到位后,客户端可以块的形式上传文件。 让我们首先创建一个简单的HTML表单来获取用户的输入。

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="tus_file" id="tus-file" />
    <input type="submit" value="Upload" />
</form>

提交表单后,我们需要按照几个步骤来处理上传。

  1. 创建一个 tus-php 客户端对象
// Tus client

$client = new \\TusPhp\\Tus\\Client('http://server.tus.local');

上面代码中的第一个参数是你的tus服务器地址。

2. 使用文件元数据初始化客户端

为了确保上传文件的唯一性,我们需要给每个上传的文件以唯一标识。这样在文件中断后续传的时候,服务器就可以很清晰地辨识出,哪几个片段是属于同一个文件得。这个标识码可以自己指定,也可以由系统生成。

// 设置标识码和文件元数据

$client->setKey($uploadKey)
    ->file($_FILES['tus_file']['tmp_name'], 'your file name');

如果不想指定标识码,可以这样写,由系统会自动生成:

$client->file($_FILES['tus_file']['tmp_name'], 'your file name');

$uploadKey = $client->getKey(); // Unique upload key

3. 分块上传文件

// $chunkSize 是以字节为单位的,例如 5000000 等于 5 MB

$bytesUploaded = $client->upload($chunkSize);

当你想要续传下一块的时候,就可以带上同样的标识码参数来续传。

// 在下一个请求中续传文件

$bytesUploaded = $client->setKey($uploadKey)->upload($chunkSize);

文件全部上传完成后,默认情况下,服务器会使用 sha256 来校验文件总和,以确保不会有丢失的文件。

使用 tus-js-client 客户端处理文件上传

tus 协议的团队还开发了一个模块化的文件上传插件 Uppy。这个插件可以在官方 tus-js-client 和 tus-php 服务器之间建立连接。也就是说我们可以使用 php 配合 js 来实现文件上传了。

uppy.use(Tus, {
  endpoint: 'https://server.tus.local/files/', // 你的 tus 服务器
  resume: true,
  autoRetry: true,
  retryDelays: [0, 1000, 3000, 5000]
})

分块上传

tus-php 服务器支持 concatenation 扩展,可以把多次上传的文件合为一个文件。因此,我们可以在客户端支持并行上传以及非连续的分块文件上传。

使用 tus-php 实现分块上传

tus-partial-upload.php

<?php

// 文件唯一标识码
$uploadKey = uniqid();

$client->setKey($uploadKey)->file('/path/to/file', 'chunk_a.ext');

// 从第 1000  个字节开始上传 10000 字节
$bytesUploaded = $client->seek(1000)->upload(10000);
$chunkAkey     = $client->getKey();

// 从 第 0 个字节开始上传 10000 字节
$bytesUploaded = $client->setFileName('chunk_b.ext')->seek(0)->upload(1000);
$chunkBkey     = $client->getKey();

// 从第 11000 个字节  (10000 +  1000) 开始上传剩余的字节
$bytesUploaded = $client->setFileName('chunk_c.ext')->seek(11000)->upload();
$chunkCkey     = $client->getKey();

// 把分块上传的文件组合起来
$client->setFileName('actual_file.ext')->concat($uploadKey, $chunkAkey, $chunkBkey, $chunkCkey);

分块上传的完整例子 在这里.

总结

由于 tus-php 项目 本身还出于初级阶段,后面可能还会有一些改动。在 example 文件夹里,有三个不同的例子供你参考。如果任何问题或者建议,欢迎留言交流。

Happy Coding!

关于PHP中如何使用TUS协议来实现大文件的断点续传的文章就分享到这,如果对你有帮助欢迎继续关注我们哦

本文来自投稿,不代表科技代码立场,如若转载,请注明出处https://www.cwhello.com/41054.html

如有侵犯您的合法权益请发邮件951076433@qq.com联系删除

(0)
上一篇 2022年6月19日 23:32
下一篇 2022年6月19日 23:32

相关推荐

  • 详解PHP 如何对接 paypal 支付

    环境准备注册paypal账号注册paypal开发者账号创建paypal沙盒测试账户创建paypal应用下载PHP SDK实现支付实现支付成功回调实现退款更多API代码模板注册paypal账号www.paypal.com 注册商家账户选择,”创建商家用户”...

    2022年6月21日
    0301
  • 如何用PHP生成微信小程序图。

    如何用PHP生成微信小程序分享图随着微信小程序的普及,越来越多的企业和个人开始将微信小程序作为自己的营销工具。在微信小程序的推广中,分享图是一个非常重要的环节。分享图的好坏,直接影响了用户对小程序的第...

    2023年6月3日
    01
  • 深入了解PHP反射API!

    PHP中的反射API就像Java中的java.lang.reflect包一样。它由一系列可以分析属性、方法和类的内置类组成。它在某些方面和对象函数相似,比如get_class_vars(),但是更加灵活,而且可以提供更多信息。反射API也可与P...

    2022年6月11日
    0134
  • 重蔚php学习第二十八天——引用文件(载入文件)

    相关函数 l  require()  :载入某个文件 l  include()  :载入某个文件 l  require_once() :载入某个文件,只载入一次 l  include_once() :载入某个文件,只载入一次 主要作用: 1)网站整体布局     (前台) ...

    2017年10月4日 PHP自学教程
    0408
  • (实用篇)php无限遍历目录

    使用的函数有: isset()判断某个变量是否定义 chdir() 将当前目录改变为指定的目录。 opendir() 打开目录。 readdir()读取目录。 getcwd()。获取当前目录。 还用到了for  if  GET传值 大概就这些: 下面...

    2016年10月24日
    0292
  • Redis在PHP应用中的集群监控。

    Redis是一种基于内存的开源数据结构存储系统,广泛用于缓存、消息队列、任务分发等场景。在PHP应用中,Redis常常扮演着重要的角色。随着业务的不断扩展,Redis集群的规模也会逐渐增大,如何进行有效的监控是保障...

    2023年5月21日
    02
  • 基于canvasJS在PHP中制作动态图表详解

    CanvasJS是一个JavaScript库,用于轻松为网页创建其他类型的图表。例如条形图,饼图,柱形图,面积图,折线图等。让我们以需要创建一个图表的示例为例,在该图表中我们可以显示每月销售和购买的产品。我们将考虑...

    2022年6月14日
    0131
  • 一文了解PHP中的进程和进程间通信

    本篇文章带大家了解一下PHP中的进程和进程间通信。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。环境php中的进程是以扩展的形式来完成。通过这些扩展,我们能够很轻松的完成进程的一系列动...

    2023年3月29日
    00

联系我们

QQ:951076433

在线咨询:点击这里给我发消息邮件:951076433@qq.com工作时间:周一至周五,9:30-18:30,节假日休息