搜尋
首頁後端開發php教程PHP 中使用 TUS 協定來實現大檔案的斷點續傳

你是否曾經為大檔案上傳而苦惱?如果檔案上傳的過程中,因為某些原因中斷了,是否可以從中斷的位置繼續上傳,而不用重新上傳整個檔案?如果你有這樣的困惑,那麼請繼續閱讀下面的內容。

在現代網站應用程式中,上傳檔案是非常常見的。在任何語言中,透過使用一些工具,都可以實現文件上傳的功能。但是,如果處理大檔案上傳的需求,還是有點麻煩的。

假如你此時正在上傳一個很大的文件,大約一個小時過去了,進度是 90%。突然斷網了或是瀏覽器崩潰了,上傳的程式退出,你要再全部重新來過。真的很不爽,對不對?還有更讓人鬱悶的是,如果你的網路速度很慢,那麼,無論你重來多少次,你都不可能上傳成功。

在 PHP 中,我們可以試著利用 tus 協定的斷點續傳功能來解決這個問題。

什麼是 tus?

Tus 是基於 HTTP 的  檔案斷點續傳開放式協定。斷點續傳的意思是不管是用戶自行中斷,還是因為網路等原因的意外中斷,都可以從中斷的地方繼續上傳,而不會重新開始。

Tus 協定是在 2017 年5月被​​ Vimeo 採用的。

為什麼用tus?

引用Vimeo 的部落格:

我們之所以決定用tus,是因為它能以簡潔開放的形式,將文件上傳的過程標準化。這種標準化有利於 API 的開發者更專注於應用程式本身的邏輯,而非檔案上傳的過程。

使用這種方式上傳的另一個好處是,你可以在筆記本上開始上傳文件,然後再轉到手機或其他裝置繼續上傳同一個文件,這可以極大地提升用戶體驗。

PHP 中使用 TUS 協定來實現大檔案的斷點續傳

圖片: Tus 大致的工作流程

#開始

第一步,載入依賴。

$ composer require ankitpokhrel/tus-php

tus-php 是用於 tus 斷點續傳協定 v1.0.0 的一個的純 PHP 框架,完美實現了 服務端與客戶端的互動 。

更新: 現在 Vimeo 官方 PHP 函式庫 的 v3 用的是 TusPHP

建立一個處理請求的服務端

你可以像下面這樣建立一個服務端.

// 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}

查看協定細則 取得更多關於路由的訊息。

如果你是用類似 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>

提交表單後,我們需要按照幾個步驟來處理上傳。

建立一個 tus-php 用戶端物件

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

上面程式碼中的第一個參數是你的 tus 伺服器位址。

2. 使用檔案元資料初始化客戶端

為了確保上傳檔案的唯一性,我們需要給每個上傳的檔案以唯一標識。這樣在文件中斷後續傳的時候,伺服器就可以很清楚辨識出,哪幾個片段是屬於同一個文件得。這個標識碼可以自己指定,也可以由系統產生。

// 设置标识码和文件元数据
$client->setKey($uploadKey)
    ->file($_FILES[&#39;tus_file&#39;][&#39;tmp_name&#39;], &#39;your file name&#39;);

如果不想指定標識碼,可以這樣寫,由系統會自動產生:

$client->file($_FILES[&#39;tus_file&#39;][&#39;tmp_name&#39;], &#39;your file name&#39;);
$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: &#39;https://server.tus.local/files/&#39;, // 你的 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(&#39;/path/to/file&#39;, &#39;chunk_a.ext&#39;);
// 从第 1000  个字节开始上传 10000 字节
$bytesUploaded = $client->seek(1000)->upload(10000);
$chunkAkey     = $client->getKey();
// 从 第 0 个字节开始上传 10000 字节
$bytesUploaded = $client->setFileName(&#39;chunk_b.ext&#39;)->seek(0)->upload(1000);
$chunkBkey     = $client->getKey();
// 从第 11000 个字节  (10000 +  1000) 开始上传剩余的字节
$bytesUploaded = $client->setFileName(&#39;chunk_c.ext&#39;)->seek(11000)->upload();
$chunkCkey     = $client->getKey();
// 把分块上传的文件组合起来
$client->setFileName(&#39;actual_file.ext&#39;)->concat($uploadKey, $chunkAkey, $chunkBkey, $chunkCkey);

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

总结

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

以上是PHP 中使用 TUS 協定來實現大檔案的斷點續傳的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
解釋負載平衡如何影響會話管理以及如何解決。解釋負載平衡如何影響會話管理以及如何解決。Apr 29, 2025 am 12:42 AM

負載均衡會影響會話管理,但可以通過會話複製、會話粘性和集中式會話存儲解決。 1.會話複製在服務器間複製會話數據。 2.會話粘性將用戶請求定向到同一服務器。 3.集中式會話存儲使用獨立服務器如Redis存儲會話數據,確保數據共享。

說明會話鎖定的概念。說明會話鎖定的概念。Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

有其他PHP會議的選擇嗎?有其他PHP會議的選擇嗎?Apr 29, 2025 am 12:36 AM

PHP會話的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。 1.Cookies通過在客戶端存儲數據來管理會話,簡單但安全性低。 2.Token-basedAuthentication使用令牌驗證用戶,安全性高但需額外邏輯。 3.Database-basedSessions將數據存儲在數據庫中,擴展性好但可能影響性能。 4.Redis/Memcached使用分佈式緩存提高性能和擴展性,但需額外配

在PHP的上下文中定義'會話劫持”一詞。在PHP的上下文中定義'會話劫持”一詞。Apr 29, 2025 am 12:33 AM

Sessionhijacking是指攻擊者通過獲取用戶的sessionID來冒充用戶。防範方法包括:1)使用HTTPS加密通信;2)驗證sessionID的來源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

PHP的完整形式是什麼?PHP的完整形式是什麼?Apr 28, 2025 pm 04:58 PM

文章討論了PHP,詳細介紹了其完整形式,在We​​b開發中的主要用途,與Python和Java的比較以及對初學者的學習便利性。

PHP如何處理形式數據?PHP如何處理形式數據?Apr 28, 2025 pm 04:57 PM

PHP使用$ \ _ post和$ \ _獲取超級全局的php處理數據,並通過驗證,消毒和安全數據庫交互確保安全性。

PHP和ASP.NET有什麼區別?PHP和ASP.NET有什麼區別?Apr 28, 2025 pm 04:56 PM

本文比較了PHP和ASP.NET,重點是它們對大規模Web應用程序,性能差異和安全功能的適用性。兩者對於大型項目都是可行的,但是PHP是開源和無關的,而ASP.NET,

PHP是對病例敏感的語言嗎?PHP是對病例敏感的語言嗎?Apr 28, 2025 pm 04:55 PM

PHP的情況敏感性各不相同:功能不敏感,而變量和類是敏感的。最佳實踐包括一致的命名和使用對案例不敏感的功能進行比較。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具