分片上传适用于较大对象的上传,其原理是将数据源切分成多个分片分别上传,最后再合并生成最终的对象。
使用 TOS 分片上传接口步骤如下:
注意
以下示例展示了通过分片上传实现本地大文件上传的完整代码:
<?php // 假设使用 composer 安装 require_once __DIR__ . '/vendor/autoload.php'; use Tos\TosClient; use Tos\Exception\TosClientException; use Tos\Exception\TosServerException; use Tos\Model\CompleteMultipartUploadInput; use Tos\Model\CreateMultipartUploadInput; use Tos\Model\Enum; use Tos\Model\UploadedPart; use Tos\Model\UploadPartInput; use GuzzleHttp\Psr7\Utils; $file = null; try { $client = new TosClient([ 'region' => 'your region', 'endpoint' => 'your endpoint', // 从环境变量中获取访问密钥 'ak' => getenv('TOS_ACCESS_KEY'), 'sk' => getenv('TOS_SECRET_KEY'), ]); $bucket = 'bucket-test'; $key = 'key-test'; // 步骤一:创建分片上传任务 $input = new CreateMultipartUploadInput($bucket, $key); // 设置对象 ACL $input->setACL(Enum::ACLPublicRead); // 设置对象 StorageClass $input->setStorageClass(Enum::StorageClassStandard); // 设置对象自定义元数据 $input->setMeta(['aaa' => 'bbb', '中文键' => '中文值']); // 设置对象 Content-Type $input->setContentType('text/plain'); $output = $client->createMultipartUpload($input); echo $output->getRequestId() . PHP_EOL; echo 'createMultipartUpload succeed' . PHP_EOL; // 获取 UploadID $uploadId = $output->getUploadID(); // 步骤二:上传多个分片 // 假设本地大文件路径为 local_big_file_path $localBigFilePath = 'local_big_file_path'; // 假设按照 20MB 切分大文件 $partSize = intval(20 * 1024 * 1024); $fileSize = filesize($localBigFilePath); $partCount = intval($fileSize / $partSize); if (($lastPartSize = $fileSize % $partSize) !== 0) { $partCount++; } else { $lastPartSize = $partSize; } $parts = []; for ($i = 0; $i < $partCount; $i++) { $partNumber = $i + 1; $file = fopen($localBigFilePath, 'r'); // 设置当前上传的文件起始位置 fseek($file, $partSize * $i, 0); $input = new UploadPartInput($bucket, $key, $uploadId, $partNumber); if ($i === $partCount - 1) { // 处理最后一个分片 $input->setContentLength($lastPartSize); } else { $input->setContentLength($partSize); } $input->setContent($file); $output = $client->uploadPart($input); echo $output->getRequestId() . PHP_EOL; echo sprintf('upload part %d succeed', $partNumber) . PHP_EOL; if (is_resource($file)) { fclose($file); } // 收集所有分片 $parts[] = new UploadedPart($partNumber, $output->getETag()); } // 步骤三:合并分片 $input = new CompleteMultipartUploadInput($bucket, $key, $uploadId, $parts); $output = $client->completeMultipartUpload($input); echo $output->getRequestId() . PHP_EOL; echo 'completeMultipartUpload succeed' . PHP_EOL; } catch (TosClientException $ex) { echo $ex->getMessage() . PHP_EOL; } catch (TosServerException $ex) { echo $ex->getRequestId() . PHP_EOL; echo $ex->getStatusCode() . PHP_EOL; echo $ex->getErrorCode() . PHP_EOL; } finally { if (is_resource($file)) { fclose($file); } }