O Object Storage Service (OSS) oferece um recurso de upload multipartido para objetos grandes. Esse processo divide o objeto em partes menores, envia cada uma independentemente e, em seguida, chama a API CompleteMultipartUpload para combiná-las em um único objeto. Isso permite retomar uploads interrompidos.
Procedimento
Para enviar um objeto com upload multipartido, siga estas etapas:
-
Inicialize uma tarefa de upload multipartido.
Chame $ossClient->initiateMultipartUpload para obter um ID de upload exclusivo no OSS.
-
Envie as partes.
Chame
$ossClient->uploadPartpara enviar as partes.NotaO número da parte identifica sua posição dentro do objeto. Enviar dados com o mesmo número sobrescreve a parte existente.
O OSS retorna o hash MD5 dos dados recebidos no cabeçalho ETag da resposta.
O OSS calcula o hash MD5 dos dados enviados e o compara com o hash calculado pelo SDK. Em caso de divergência, o sistema retorna o código de erro InvalidDigest.
-
Conclua a tarefa de upload multipartido.
Chame
$ossClient->completeMultipartUploadpara combinar todas as partes em um objeto completo.
Código de exemplo completo de uma tarefa de upload multipartido
O exemplo a seguir mostra o processo completo de upload multipartido:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
use OSS\Core\OssUtil;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt.
$object = 'exampledir/exampleobject.txt';
// Specify the full path of the local file that you want to upload.
$uploadFile = 'D:\\localpath\\examplefile.txt';
$initOptions = array(
OssClient::OSS_HEADERS => array(
// Specify the caching behavior of the web page when the object is downloaded.
// 'Cache-Control' => 'no-cache',
//Specify the name of the object when the object is downloaded.
// 'Content-Disposition' => 'attachment;filename=oss_download.jpg',
// Specify the validity period of the request. Unit: milliseconds.
// 'Expires' => 150,
// If set to true, prevents this upload from overwriting an existing object with the same name.
//'x-oss-forbid-overwrite' => 'true',
// Specify the server-side encryption method that you want to use to encrypt each part of the object.
// 'x-oss-server-side-encryption'=> 'KMS',
// Specify the algorithm that you want to use to encrypt the object.
// 'x-oss-server-side-data-encryption'=>'SM4',
// Specify the ID of the customer master key (CMK) that is managed by Key Management Service (KMS).
//'x-oss-server-side-encryption-key-id' => '9468da86-3509-4f8d-a61e-6eab1eac****',
// Specify the storage class of the object.
// 'x-oss-storage-class' => 'Standard',
// Specify tags for the object. You can specify multiple tags for the object at a time.
// 'x-oss-tagging' => 'TagA=A&TagB=B',
),
);
/**
* Step 1: Initiate a multipart upload task and obtain the upload ID.
*/
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
// Obtain the upload ID. The upload ID is the unique identifier of a multipart upload task. You can perform related operations such as canceling or querying the multipart upload task based on the upload ID.
$uploadId = $ossClient->initiateMultipartUpload($bucket, $object, $initOptions);
print("initiateMultipartUpload OK" . "\n");
// Cancel the multipart upload task or list uploaded parts based on the upload ID.
// If you want to cancel a multipart upload task based on the upload ID, obtain the upload ID after you call the InitiateMultipartUpload operation to initiate the multipart upload task.
// If you want to list the uploaded parts in a multipart upload task based on the upload ID, obtain the upload ID after you call the InitiateMultipartUpload operation to initiate the multipart upload task but before you call the CompleteMultipartUpload operation to complete the multipart upload task.
//print("UploadId: " . $uploadId . "\n");
} catch(OssException $e) {
printf($e->getMessage() . "\n");
return;
}
/*
* Step 2: Upload parts.
*/
// The minimum part size is 100 KB and the maximum part size is 5 GB. The size of the last part can be less than 100 KB.
$partSize = 10 * 1024 * 1024;
$uploadFileSize = sprintf('%u',filesize($uploadFile));
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
$fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
$toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
$upOptions = array(
// Upload the object.
$ossClient::OSS_FILE_UPLOAD => $uploadFile,
// Specify part numbers.
$ossClient::OSS_PART_NUM => ($i + 1),
// Specify the position from which the multipart upload task starts.
$ossClient::OSS_SEEK_TO => $fromPos,
// Specify the object length.
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
// Specify whether to enable MD5 verification. The value true specifies that MD5 verification is enabled.
$ossClient::OSS_CHECK_MD5 => $isCheckMd5,
);
// Enable MD5 verification.
if ($isCheckMd5) {
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
$upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
}
try {
// Upload the parts.
$responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
printf("initiateMultipartUpload, uploadPart - part#{$i} OK\n");
} catch(OssException $e) {
printf("initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
printf($e->getMessage() . "\n");
return;
}
}
// $uploadParts is an array that consists of the ETag and part number of each part.
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* Step 3: Complete the multipart upload task.
*/
$comOptions['headers'] = array(
// Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is complete. In this example, this parameter is set to true, which specifies that the uploaded object that has the same name as the existing object does not overwrite the existing object.
// 'x-oss-forbid-overwrite' => 'true',
// If you set the x-oss-complete-all parameter to yes, OSS lists all parts that are uploaded by using the current upload ID, sorts the parts by part number, and then performs the CompleteMultipartUpload operation.
// 'x-oss-complete-all'=> 'yes'
);
try {
// Provide the list of all uploaded parts (PartNumber and ETag). OSS will verify each part before combining them into the final object.
$ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts,$comOptions);
printf( "Complete Multipart Upload OK\n");
} catch(OssException $e) {
printf("Complete Multipart Upload FAILED\n");
printf($e->getMessage() . "\n");
return;
}
Envio de arquivo local via upload multipartido
O código de exemplo a seguir demonstra como enviar um arquivo local para o OSS com upload multipartido:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt.
$object = 'exampledir/exampleobject.txt';
// Specify the full path of the local file that you want to upload.
$file = 'D:\\localpath\\examplefile.txt';
$options = array(
OssClient::OSS_CHECK_MD5 => true,
OssClient::OSS_PART_SIZE => 1,
);
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$ossClient->multiuploadFile($bucket, $object, $file, $options);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Envio de diretório local via upload multipartido (PHP SDK V1)
Este exemplo ilustra o envio de um diretório local, incluindo todos os seus arquivos, para o OSS com upload multipartido:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the local directory that you want to upload.
$localDirectory = "D:\\localpath";
// Specify the prefix of the directory.
$prefix = "samples/codes/";
try {
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$ossClient->uploadDir($bucket, $prefix, $localDirectory);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Cancelamento de tarefa de upload multipartido (PHP SDK V1)
Use o método $ossClient->abortMultipartUpload para cancelar uma tarefa de upload multipartido. Após o cancelamento, o ID de upload torna-se inválido para envio de novas partes e as partes já enviadas são excluídas.
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt.
$object = 'exampledir/exampleobject.txt';
// Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. You can obtain the upload ID from the response to the InitiateMultipartUpload operation.
$upload_id = '0004B999EF518A1FE585B0C9360D****';
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$ossClient->abortMultipartUpload($bucket, $object, $upload_id);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Listagem de partes enviadas (PHP SDK V1)
Use o método listParts para listar todas as partes enviadas associadas a um ID de upload específico.
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt.
$object = 'exampledir/exampleobject.txt';
// Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. You can obtain the upload ID from the response to the InitiateMultipartUpload operation. You must obtain the upload ID before you call the CompleteMultipartUpload operation to complete the multipart upload task.
$upload_id = '0004B999EF518A1FE585B0C9360D****';
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$listPartsInfo = $ossClient->listParts($bucket, $object, $uploadId);
foreach ($listPartsInfo->getListPart() as $partInfo) {
print($partInfo->getPartNumber() . "\t" . $partInfo->getSize() . "\t" . $partInfo->getETag() . "\t" . $partInfo->getLastModified() . "\n");
}
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Listagem de tarefas de upload multipartido (PHP SDK V1)
Use o método listMultipartUploads para listar todas as tarefas de upload multipartido em andamento. Tarefas em andamento são aquelas iniciadas, mas ainda não concluídas ou canceladas.
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket.
$bucket= 'examplebucket';
$options = array(
'delimiter' => '/',
'max-uploads' => 100,
'key-marker' => '',
'prefix' => '',
'upload-id-marker' => ''
);
try {
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$listMultipartUploadInfo = $ossClient->listMultipartUploads($bucket, $options);
} catch(OssException $e) {
printf(__FUNCTION__ . ": listMultipartUploads FAILED\n");
printf($e->getMessage() . "\n");
return;
}
printf(__FUNCTION__ . ": listMultipartUploads OK\n");
$listUploadInfo = $listMultipartUploadInfo->getUploads();
var_dump($listUploadInfo);
A tabela a seguir descreve os parâmetros incluídos em $options no código de exemplo anterior.
|
Parâmetro |
Descrição |
|
delimiter |
Caractere delimitador usado para agrupar nomes de objetos. Objetos cujos nomes contêm a mesma string entre o prefixo e a próxima ocorrência do delimitador são agrupados como um único elemento de resultado no parâmetro commonPrefixes. |
|
key-marker |
Usado em conjunto com upload-id-marker para definir o ponto inicial da listagem. A lista incluirá apenas tarefas cujas chaves de objeto sejam alfabeticamente posteriores a este valor. |
|
max-uploads |
Número máximo de tarefas de upload multipartido a retornar na lista atual. Valor máximo: 1000. Valor padrão: 1000. |
|
prefix |
Prefixo obrigatório nos nomes dos objetos retornados. Nota
Ao usar um prefixo na consulta, os nomes dos objetos retornados incluirão esse prefixo. |
|
upload-id-marker |
ID de upload da tarefa de upload multipartido a partir da qual a listagem começa. Este parâmetro é usado junto com key-marker. Se key-marker não for especificado, upload-id-marker será ignorado. Quando key-marker é definido, o resultado da consulta inclui:
|
Referências
Para acessar o código de exemplo completo sobre upload multipartido, visite o GitHub.
-
O upload multipartido envolve três operações de API:
Inicializar upload multipartido: InitiateMultipartUpload.
Enviar uma parte: UploadPart.
Concluir upload multipartido: CompleteMultipartUpload.
Cancelar upload multipartido: AbortMultipartUpload.
Listar partes enviadas: ListParts.
Listar uploads multipartido em andamento: ListMultipartUploads.