PHP 中使用 TUS 协议来实现大文件的断点续传
为什么用 tus?
引用 Vimeo 的博客:
我们之所以决定用 tus,是因为它能以简洁开放的形式,将文件上传的过程标准化。这种标准化有利于 API 的开发
Tus 协议是在 2017 年5月被 Vimeo 采用的。 为什么用 tus? 引用 Vimeo 的博客: 我们之所以决定用 tus,是因为它能以简洁开放的形式,将文件上传的过程标准化。这种标准化有利于 API 的开发者更加专注于应用本身的逻辑,而非文件上传的过程。 使用这种方式上传的另一个好处是,你可以在笔记本上开始上传文件,然后又转到手机或者其他设备继续上传同一个文件,这可以极大地提升用户体验。 开始 第一步,加载依赖。 $ 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 是 因此,基于我们上面的 Nginx 配置,我们可以通过 来访问到我们的 tus 终端. 基于 RESTful 风格的端点配置: # 获取有关服务器目前配置的信息\ OPTIONS /files # 检查上传的文件是否合法\ HEAD /files/{upload-key} # 创建\ POST /files # 修改\ PATCH /files/{upload-key} # 删除\ DELETE /files/{upload-key} 如果你是用类似于 Laravel 的框架,那么你就不需要在配置文件里定义这些了, 可以直接定义路由来访问 tus 的基础端点。我们会在另外的教程里介绍相关细节。 使用 tus-php 客户端处理上传 服务器到位后,客户端可以块的形式上传文件。让我们首先创建一个简单的 HTML 表单来获取用户的输入。 提交表单后,我们需要按照几个步骤来处理上传。 创建一个 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 来校验文件总和PHP文件,以确保不会有丢失的文件。 使用 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); (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |