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

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

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

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

d1d36e5929960035e23a44db4839d18d.png

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

首先什么是tus?

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

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

为什么是tus?

引用Vimeo的博客:

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

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

dbaa32fa92493d4b1ec2e46c355081a1.png
基本的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等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java使用xml存储数据_用存储过程和 JAVA 写报表数据源有什么弊端?

用存储过程和 JAVA 写报表数据源有什么弊端&#xff1f;跟着小编一起来一看一下吧&#xff01;我们在报表开发中经常会使用存储过程准备数据&#xff0c;存储过程支持分步计算&#xff0c;可以实现非常复杂的计算逻辑&#xff0c;为报表开发带来便利。所以&#xff0c;报表开发…

MAC OS上JAVA1.6 升级1.7,以及 maven3.2.1配置

一、我的MAC系统 预装的Jdk是1.6&#xff0c;由于需要使用eclipse MARs 2版本&#xff0c;故需要升级到1.7 二、下载JAVA jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 不知道为什么直接下非常慢&#xff0c;后来用的迅雷就超级快…

sql server 创建唯一性非聚集索引语句_数据库专题—索引原理

深入浅出数据库索引原理参见:https://www.cnblogs.com/aspwebchh/p/6652855.html1.为什么给表加上主键&#xff1f;1.平时创建表的时候&#xff0c;都会给表加上主键。如果没有主键的表&#xff0c;数据会一行行的排列在磁盘上&#xff0c;查找一个数据需要一条条的进行对比。而…

oracle数据库更新语句_20_手把手教你学Python之操作数据库

数据库是数据的仓库&#xff0c;将大量数据按照一定的方式组织并存储起来&#xff0c;方便进行管理和维护&#xff0c;例如快速检索和统计等。数据库的主要特点&#xff1a;以一定的方式组织、存储数据&#xff1b;能为多个用户共享&#xff1b;与程序彼此独立。……数据库管理…

查询Oracle正在执行的sql语句

--查询Oracle正在执行的sql语句及执行该语句的用户 [sql] view plaincopy SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, paddr, sql_text 正在执行的SQL, b.machine 计算机名 FROM v$p…

WinForm 清空界面控件值的小技巧

WinForm 清空界面控件值的小技巧 原文:WinForm 清空界面控件值的小技巧在WinForm里面有时候需要清空自己输入内容或是选择的选项&#xff0c;以便重新操作流程&#xff0c;那么一般你是怎么清空界面各个控件值的呢&#xff1f;如果窗体里面控件&#xff0c;尤其是TextBox控件比…

virsh的使用

2019独角兽企业重金招聘Python工程师标准>>> ###这里最先要完成的是对网卡的配置(os ubuntu14.04) 目的是实现vm上是以桥接的方式联网 修改/etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback #auto eth0…

SQL Server - 高可用与灾难恢复(HADR)技术 -- AlwaysOn可用性组(理论篇)

因为篇幅原因&#xff0c;AlwaysOn可用性组被拆成了两部分&#xff1a;理论部分和实战部分。而实战部分又被拆成了准备工作和AlwaysOn可用性组搭建。 三篇文章各自的链接&#xff1a; SQL Server ->> 高可用与灾难恢复&#xff08;HADR&#xff09;技术 -- AlwaysOn&…

python 3.6.5编译安装_Linux系统安装Python3.6.5

Linux系统安装Python3.6.5 1、下载Python3.6.5 wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz 如果报command not found则执行&#xff1a;yum -y install wget命令后再进行下载 也可下载好安装包进行手动上传 2、安装Python3.6可能使用的依赖 yum install o…

从传统运维到云运维演进历程之软件定义存储(一)

运维是企业业务系统从规划、设计、实施、交付到运维的最后一个步骤&#xff0c;也是重要的步骤。运维从横向、纵向分可以分为多个维度和层次&#xff0c;本文试图抛开这纷繁复杂的概念&#xff0c;讲述一个传统的企业级运维人员转型到云运维人员&#xff0c;尤其是软件定义存储…

Abp Uow 设计

初始化入口 在AbpKernelModule类中&#xff0c;通过UnitOfWorkRegistrar.Initialize(IocManager) 方法去初始化 1 /// <summary>2 /// This class is used to register interceptor for needed classes for Unit Of Work mechanism.3 /// </summary>4 …

python3.8 实现鼠标自动移动_“新生报到”!【移动机器人 HD-1500】负载1500kg,实现了重型货物运输的自动化...

2020年第三季度欧姆龙自动化&#xff08;中国&#xff09;有限公司新品【移动机器人 HD-1500】即日起在中国市场首次对外发布&#xff0c;实现了重型货物运输的自动化。这款最新的自动化移动机器人重型载荷能力为1500 kg&#xff01;更高的载荷能力可以令客户实现以前无法实现的…

android 监听本机网络请求_fiddler如何抓取https请求实现fiddler手机抓包-证书安装失败100%解决...

一、HTTP协议和HTTPS协议。(1) HTTPS协议HTTP协议SSL协议&#xff0c;默认端口&#xff1a;443(2) HTTP协议&#xff08;HyperText Transfer Protocol&#xff09;&#xff1a;超文本传输协议。默认端口&#xff1a;80&#xff0c;其中包含请求和响应两部分&#xff0c;其中请求…

C#的四舍五入函数

2019独角兽企业重金招聘Python工程师标准>>> 1.四舍六入&#xff08;国外的四舍五入&#xff09; Math.Round&#xff08;num&#xff09;; 2.四舍五入 Math.Round(num,MidpointRounding.AwayFromZero); 转载于:https://my.oschina.net/CrazyBoy1024/blog/746268

【BZOJ2243】 [SDOI2011]染色

Description 给定一棵有n个节点的无根树和m个操作&#xff0c;操作有2类&#xff1a; 1、将节点a到节点b路径上所有点都染成颜色c&#xff1b; 2、询问节点a到节点b路径上的颜色段数量&#xff08;连续相同颜色被认为是同一段&#xff09;&#xff0c;如“112221”由3段组成&am…

数字信号处理的fpga实现_FPGA数字信号处理:通信类I/Q信号及产生

大侠好&#xff0c;欢迎来到FPGA技术江湖&#xff0c;江湖偌大&#xff0c;相见即是缘分。大侠可以关注FPGA技术江湖&#xff0c;在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源&#xff0c;或者一起煮酒言欢。大侠好&#xff0c;“宁夏李治廷”再一次和各位见…

iic通讯协议

IIC总线 一般串行数据通讯都有时钟和数据之分,有异步和同步之别. 有单线,双线和三线等. I2C肯定是2线的(不算地线). I2C协议确实很科学,比3/4线的SPI要好,当然线多通讯速率相对就快了. I2C的原则是: 在SCL1(高电平)时,SDA千万别忽悠!!! 否则,SDA下跳则"判罚"为&…

使用 Python 切割图片

刚好我有张 PNG 图片需要均匀切割&#xff0c;刚好我不会 PhotoShop&#xff0c;刚好我想用 Python 来练练手。 于是撸袖子码脚本。 import os from PIL import Imagedef splitimage(src, rownum, colnum, dstpath):img Image.open(src)w, h img.sizeif rownum < h and co…

python数据分析知识点_Python数据分析--Pandas知识点(三)

本文主要是总结学习pandas过程中用到的函数和方法, 在此记录, 防止遗忘. 下面将是在知识点一, 二的基础上继续总结. 前面所介绍的都是以表格的形式中展现数据, 下面将介绍Pandas与Matplotlib配合绘制出折线图, 散点图, 饼图, 柱形图, 直方图等五大基本图形. Matplotlib是python…

SPI通讯协议

SPI&#xff1a;高速同步串行口。是一种标准的四线同步双向串行总线。 SPI&#xff0c;是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM&#xff0c;FLASH&#x…