曾经尝试过用PHP上传大文件吗?想知道您是否可以从上次中断的地方继续上传,而不会在遇到任何中断的情况下再次重新上传整个数据?如果您觉得这个场景很熟悉,请接着往下阅读。

文件上传是我们几乎所有现代Web项目中的一项很常见的任务。在任何语言中,有了可用的工具,实现文件上传功能都不难。但是,对于大文件上传,这个事情还是有些让人头疼。

假设您正在尝试上传相当大的文件。您已经等待了一个多小时,上传率为90%。然后突然,您的连接断开或浏览器崩溃。上传被中止,您需要从头开始上传。这很令人沮丧,不是吗?更糟糕的是,如果您的连接速度较慢,就像世界上许多地方一样,无论尝试多少次,每次都只能上传第一部分内容。无论你重来多少次,你都不可能上传成功。你的心态扛得住嘛?!?!

在这篇文章中,我们将尝试通过使用tus协议以可恢复块的形式上传文件来解决PHP中的此问题。

首先什么是tus?

Tus是用于可恢复文件上传的基于HTTP的开放协议。可恢复意味着可以在中断的地方继续工作,而不会在遇到任何中断的情况下再次重新上传整个数据。如果用户希望暂停,则中断可能会发生,或者在网络问题或服务器中断的情况下,偶然发生。

Vimeo于2017年5月采用了 Tus协议。

为什么是tus?

引用Vimeo的博客:

我们之所以决定在上载堆栈中使用tus,是因为tus协议以简洁明了的方式标准化了上载文件的过程。这种标准化将使API开发人员可以将更多的精力放在其特定于应用程序的代码上,而不必将精力放在上传过程本身上。

通过这种方式上传文件的另一个主要好处是,您可以从笔记本电脑开始上传,甚至可以继续从移动设备或任何其他设备上载相同的文件,这可以极大地提升用户体验。

基本的Tus架构

入门

从添加我们的依赖关系开始

$ composer require ankitpokhrel/tus-php

tus-php是用于tus可断续上传协议v1.0.0的纯PHP框架 服务器和客户端实现。
tus-php-for用于tus可恢复上载协议v1.0.0的纯PHP服务器和客户端 github.com

更新:Vimeo现在在其官方PHP库的v3 中将TusPHP 用于Vimeo API。

创建一个服务器来处理我们的请求

这就是简单服务器的外观。

// server.php$server   = new TusPhpTusServer('redis');
$response = $server->serve();$response->send();exit(0); // 从当前的PHP进程退出.

您需要配置服务器以响应特定的端点。例如,在Nginx中,您可以执行以下操作:

# nginx.conflocation /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}

查看协议详细信息以获取有关端点的更多信息。

如果您使用的是Laravel之类的框架,则不需要修改服务器配置,而可以在框架路由文件中定义到所有基于tus端点的路由。这个我们将在另一个教程中对此进行详细介绍。

使用 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 TusPhpTusClient('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。您可以使用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]
})

更多细节可以查看uppy的文档,还有些例子可以供你参考。

分块上传

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 协议

核心协议

核心协议描述如何继续中断的上传。这里假定你已经有一个用于上传的 RUL ,这个 URL 通常是由扩展协议 Creation创建。

所有客户端和服务端必须实现核心协议。

协议没有描述 RUL 的结构,而是留给协议的实现来决定。本文中所有展示的 URL 仅用于举例。

此外,认证和授权的实现也留给服务端来决定。

示例

用一个请求头指明应当从什么地方开始续传上传。

以下示例展示中断位置由70变为100

请求

HEAD /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1

Host: http://tus.example.org

Tus-Resumable: 1.0.0

响应

HTTP/1.1 200 OK

Upload-Offset: 70

Tus-Resumable: 1.0.0

对于给定的中断位置,客户端使用 PATCH 方法来续传。

请求

PATCH /files/24e533e02ec3bc40c387f1a0e460e216 HTTP/1.1

Host: http://tus.example.org

Content-Type: application/offset+octet-stream

Content-Length: 30

Upload-Offset: 70

Tus-Resumable: 1.0.0

[remaining 30 bytes]

响应

HTTP/1.1 204 No Content

Tus-Resumable: 1.0.0

Upload-Offset: 100

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

Happy Coding!

更多学习内容请访问从码农成为架构师的修炼之路

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处。

ideaspringboot项目上传服务器_PHP中使用 TUS 协议来实现可恢复文件上传相关推荐

  1. 使用WinHttp接口实现HTTP协议Get、Post和文件上传功能

    我实现了一个最新版本的接口,详见<实现HTTP协议Get.Post和文件上传功能--使用WinHttp接口实现>.还有基于libcurl实现的版本<实现HTTP协议Get.Post和 ...

  2. 实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现

    在<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>一文中,我已经比较详细地讲解了如何使用WinHttp接口实现各种协议.在最近的代码梳理中,我觉得Post和文件上传 ...

  3. php上传文件到三方,文件上传服务器_PHP文件上传实现上传到另一台服务器

    摘要 腾兴网为您分享:PHP文件上传实现上传到另一台服务器,作业盒子,自动刷宝,盈益云,小太阳等软件知识,以及手机mp3格式转换器,积木图纸,驾驶证分系统网站,finereader12,2017年日 ...

  4. 在ASP.NET Core 3.1 MVC中集成Vue.js V4和使用Dropzone文件上传

    目录 介绍 先决条件 Node.js的介绍 您已经安装了Node.js/NPM吗? Node/ NPM版本相关的常见错误 Vue.js简介 安装Vue.js V4 NET Core介绍 安装Visua ...

  5. 商城项目09_品牌管理菜单、快速显示开关、阿里云进行文件上传、结合Alibaba管理OSS、服务端签名后直传

    文章目录 ①. 品牌管理菜单 ②. 快速显示开关 ③. 阿里云上传概述 ④. 使用代码进行文件上传 ⑤. 结合Alibaba来管理oss ⑥. gulimall-third-party微服务 ⑦. 服 ...

  6. bpmn 文件 服务器部署,Liferay7 BPM门户开发之45: 集成Activiti文件上传部署流程BPMN模型...

    开发文件上传,部署流程模板. 首先,开发jsp页面,deploy.jsp ${RETURN_MESSAGE} 其中,上传form的action为portlet:actionURL,它的name就是在p ...

  7. SpringBoot中使用yml配置文件以及配置类实现文件上传下载路径的修改

    场景 SpringBoot+thymeleaf实现文件下载或者实现文件上传需要配置文件上传路径的地方, 不要写为固定路径,在配置文件中指定文件路径,代码中直接引用. 避免以后文件路径修改后需要修改业务 ...

  8. 第五人格服务器要维修到几点,第五人格维护登不上怎么办 服务器维护中详情...

    第五人格维护登不上怎么办?维护是最常见的,出新角色.新屠夫都是会进行维护的,而且经常会更新和维护新玩法,那么服务器维护怎么办?下面是小编给大家带来第五人格服务器维护中详情,快一起来看看吧. 第五人格服 ...

  9. php中file对象实例,AJAX_File, FileReader 和 Ajax 文件上传实例分析(php),File FileReader 可以干什么? Ajax - phpStudy...

    File, FileReader 和 Ajax 文件上传实例分析(php) File FileReader 可以干什么?Ajax文件上传例子 FileReader 对象可以读取文件的 Base64编码 ...

最新文章

  1. 全球AI报告:探索人工智能革命
  2. 大数据框架对比:Hadoop、Storm、Samza、Spark和Flink——flink支持SQL,待看
  3. tensorflow安装教程
  4. 产品观,来自微信张小龙的
  5. Java字符串、文件MD5工具类
  6. golang http 返回html文件_从零部署安装 Grpc-golang
  7. 电力系统服务器故障预案,电网预案推演系统及电网预案推演方法
  8. 小米净水器更换php教程,这种方法更换滤芯寿命更长:小米净水器
  9. 计算机怎样存储数值,(二)计算机如何保存字符和数字,并完成计算
  10. 此版本的visual studio无法打开下列项目_深度学习实现高精度钢琴曲转谱Piano transcription项目简明使用教程...
  11. win10修复计算机是哪个键,教你Win10修复系统引导文件的详细方法
  12. ARP表 MAC表 路由表
  13. geth 搭建 私有链节点
  14. 三国杀全武将台词大全(标准+神话再临+一将成名12345+SP+国战+其他+皮肤,更新中)
  15. 2008'中国地理信息系统优秀工程公示
  16. 想自己动手制作游戏动漫角色模型,教你几招,一定要看看!
  17. 用HTML+CSS+JS做一个漂亮的个人网页
  18. android 图片读写,Android读取本地照片和视频相册
  19. php中水仙花数的求法,php 求水仙花数优化
  20. oracle安装在非图形,非图形化静默安装Oracle 11g

热门文章

  1. springbootajaxhas been blocked by CORS policy: No ‘Access-Control-Allow-Origin
  2. vue 父组件 调用 子组件的方法
  3. 昨天,我的大学学习[2]
  4. 【noip模拟赛4】Matrix67的派对 暴力dfs
  5. httpservlet获取请求端IP地址
  6. java中XPATH操作xml,非常便捷
  7. MVC5+EF6 入门完整教程四
  8. 百度富文本编辑器的应用技巧---在一个页面中使用多个样式不同功能不同的编辑器...
  9. 给.net初学者的一些建议(共勉之)[转载]
  10. 网易NEI在面临前后端分离问题,所提供的完整解决方案