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.pswp.cn/news/457968.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457968.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457968.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

無密碼登陸

server A /B以root賬戶在A上無密碼ssh到B方式一ON A:ssh-keygen -t dsa -P -f ~/.ssh/id_dsa cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys chmod 644 ~/.ssh/authorized_keys service sshd restart ON B:ssh-keygen -t dsa -P -f ~/.ssh/id_dsa cat ~/.ssh/id_d…

嵌入式常見筆試題總結

預處理器&#xff08;Preprocessor&#xff09;1. 用預處理指令#define 聲明一個常數&#xff0c;用以表明1年中有多少秒&#xff08;忽略閏年問題&#xff09; #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在這想看到幾件事情&#xff1a; 1). #define 語法的基本知識…

【轉】php利用mkdir創建多級目錄

先介紹一下 mkdir() 這個函數&#xff1a; mkdir($path,0777,true); 第一個參數&#xff1a;必須&#xff0c;代表要創建的多級目錄的路徑&#xff1b; 第二個參數&#xff1a;設定目錄的權限&#xff0c;默認是 0777&#xff0c;意味著最大可能的訪問權&#xff1b; 第三個參數…

java使用xml存儲數據_用存儲過程和 JAVA 寫報表數據源有什么弊端?

用存儲過程和 JAVA 寫報表數據源有什么弊端&#xff1f;跟著小編一起來一看一下吧&#xff01;我們在報表開發中經常會使用存儲過程準備數據&#xff0c;存儲過程支持分步計算&#xff0c;可以實現非常復雜的計算邏輯&#xff0c;為報表開發帶來便利。所以&#xff0c;報表開發…

GIT文件的三種狀態

對于任何一個文件&#xff0c;在 Git 內都只有三種狀態&#xff1a;已提交&#xff08;committed&#xff09;&#xff0c;已修改&#xff08;modified&#xff09;和已暫存&#xff08;staged&#xff09;。已提交表示該文件已經被安全地保存在本地數據庫 中了&#xff1b;已修…

嵌入式常見筆試題總結(2)

預處理器&#xff08;Preprocessor&#xff09;   1. 用預處理指令#define 聲明一個常數&#xff0c;用以表明1年中有多少秒&#xff08;忽略閏年問題&#xff09;   #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL   我在這想看到幾件事情&#xff1a;   1). #…

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;查找一個數據需要一條條的進行對比。而…

String,StringBuffer,StringBuilder區別

String 字符串常量StringBuffer 字符串變量&#xff08;線程安全&#xff09;StringBuilder 字符串變量&#xff08;非線程安全&#xff09; 簡要的說&#xff0c; String 類型和 StringBuffer 類型的主要性能區別其實在于 String 是不可變的對象, 因此在每次對 String 類型進行…

oracle數據庫更新語句_20_手把手教你學Python之操作數據庫

數據庫是數據的倉庫&#xff0c;將大量數據按照一定的方式組織并存儲起來&#xff0c;方便進行管理和維護&#xff0c;例如快速檢索和統計等。數據庫的主要特點&#xff1a;以一定的方式組織、存儲數據&#xff1b;能為多個用戶共享&#xff1b;與程序彼此獨立。……數據庫管理…

第十周學習進度

第十周 所花時間&#xff08;包括上課&#xff09; 10小時 代碼量&#xff08;行&#xff09; 0行 博客量&#xff08;篇&#xff09; 4篇 了解到的知識點 對各組進行評價&#xff1b;思考并回復各組 轉載于:https://www.cnblogs.com/qwer111/p/5470819.html

嵌入式常見筆試題總結(3)

1:設float a2, b4, c3&#xff1b;&#xff0c;以下C語言表達式與代數式 (ab)c計算結果不一致的是 A.(ab)*c/2 B.(1/2)*(ab)*c C.(ab)*c*1/2 D.c/2*(ab) 參考答案&#xff1a;B&#xff0c;因為a,b,c三個變量都是浮點數&#xff0c;所以在B答案中其結果是0&#xff0c;因為…

查詢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控件比…

int 取值范圍_一定范圍內的隨機數

老司機的新問題&#xff0c;取得[min, max]范圍的隨機數。C版本的rand函數很不容易用對&#xff0c;直接用rand() % (max - min 1) min&#xff0c;這個公式不對。這個公式與取最低位的算法相同&#xff0c;而隨機數的最低幾位不一定等概率。Donald Knuth博士教導我們正確的用…

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…

嵌入式常見筆試題總結(4)

1&#xff1a;用C語言實現大小端的測試 Int CheckCpu() { union { int a; char b; }c; c.a1; if(c.b1) printf(“小端”)&#xff1b; else printf&#xff08;“大端”&#xff09;&#xff1b; } 2&#xff1a;volatile的作用有哪些&#xff1f; Volatile第一變量相當于告訴編…

《java入門第一季》之類String類小案例

String類有許多獲取方法&#xff0c;API文檔里面可查看。針對獲取方法&#xff0c;給出小案例。 /** 需求&#xff1a;遍歷獲取字符串中的每一個字符* 分析&#xff1a; 用到兩個方法&#xff1a;char charAt(int index) 表示獲取字符串指定索引的字符int length() …

同字母異序詞 python_49. 字母異位次分組(Python)

題目 給定一個字符串數組&#xff0c;將字母異位詞組合在一起。字母異位詞指字母相同&#xff0c;但排列不同的字符串。 說明 所有輸入均為小寫字母。 不考慮答案輸出的順序。 示例 輸入: ["eat", "tea", "tan", "ate", "nat&quo…

嵌入式常見筆試題總結(5)

1、 如何在C中初始化一個字符數組。這個問題看似很簡單&#xff0c;但是我們要將最簡單的問題用最嚴謹的態度來對待。關鍵的地方&#xff1a;初始化、字符型、數組。最簡單的方法是char array[];。這個問題看似解決了&#xff0c;但是在初始化上好像還欠缺點什么&#xff0c;個…