O recurso de multipart upload do OSS permite dividir um objeto grande em várias partes e fazer o upload dessas partes separadamente. Após o upload de todas as partes, você pode chamar a operação CompleteMultipartUpload para combiná-las em um objeto completo.
Observações
O código de exemplo neste tópico usa a região China (Hangzhou) como exemplo. O ID da região é
cn-hangzhou. Por padrão, o OSS utiliza um endpoint público. Se você quiser acessar o OSS a partir de outros serviços da Alibaba Cloud na mesma região, use um endpoint interno. Para mais informações sobre as regiões e endpoints suportados pelo OSS, consulte OSS regions and endpoints.Para executar um multipart upload, você precisa ter a permissão
oss:PutObject. Para mais informações, consulte Grant custom access policies to a RAM user.Este tópico fornece um exemplo de como ler credenciais de acesso a partir de variáveis de ambiente. Para obter mais exemplos sobre como configurar credenciais de acesso, consulte Configure access credentials for PHP.
Fluxo do multipart upload
Um multipart upload consiste nas três etapas a seguir:
-
Inicialize um evento de multipart upload.
Chame o método InitiateMultipartUpload para obter um ID de upload globalmente exclusivo do OSS.
-
Faça o upload das partes.
Chame o método UploadPart para fazer o upload dos dados de cada parte.
NotaSe você fizer o upload de novos dados usando o mesmo número de parte, o OSS substitui os dados existentes da parte.
O OSS inclui o hash MD5 dos dados da parte recebida no cabeçalho ETag e retorna esse cabeçalho para você.
O OSS calcula o hash MD5 dos dados enviados e o compara com o hash MD5 calculado pelo kit de desenvolvimento de software (SDK). Se os dois hashes MD5 forem diferentes, o OSS retorna o código de erro InvalidDigest.
-
Conclua o multipart upload.
Após o upload de todas as partes, chame o método CompleteMultipartUpload para combinar as partes em um arquivo completo.
Código de exemplo
O código de exemplo a seguir mostra como dividir um arquivo local grande em várias partes, fazer o upload dessas partes para um bucket e, em seguida, combiná-las em um objeto completo.
<?php
// Import the autoloader file to ensure that dependency libraries can be loaded correctly.
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// Define the description of command-line arguments.
$optsdesc = [
"region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // The region where the bucket is located. (Required)
"endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // The endpoint that can be used to access OSS. (Optional)
"bucket" => ['help' => 'The name of the bucket', 'required' => True], // The name of the bucket. (Required)
"key" => ['help' => 'The name of the object', 'required' => True], // The name of the object. (Required)
];
// Convert the argument descriptions to the long option format required by getopt.
// A colon (:) after each argument indicates that the argument requires a value.
$longopts = \array_map(function ($key) {
return "$key:";
}, array_keys($optsdesc));
// Parse the command-line arguments.
$options = getopt("", $longopts);
// Check whether the required arguments exist.
foreach ($optsdesc as $key => $value) {
if ($value['required'] === True && empty($options[$key])) {
$help = $value['help']; // Obtain the help information of the argument.
echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
exit(1); // If a required argument is missing, exit the program.
}
}
// Extract values from the parsed arguments.
$region = $options["region"]; // The region where the bucket is located.
$bucket = $options["bucket"]; // The name of the bucket.
$key = $options["key"]; // The name of the object.
// Load the credential information from environment variables.
// Use EnvironmentVariableCredentialsProvider to read the Access Key ID and Access Key Secret from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// Use the default configurations of the SDK.
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // Set the credential provider.
$cfg->setRegion($region); // Set the region where the bucket is located.
$cfg->setEndpoint('http://oss-cn-hangzhou.aliyuncs.com'); // Set the endpoint.
// Create an OSS client instance.
$client = new Oss\Client($cfg);
// Initialize the multipart upload task.
$initResult = $client->initiateMultipartUpload(
new Oss\Models\InitiateMultipartUploadRequest(
bucket: $bucket,
key: $key
)
);
// Define the path of the large file and the part size.
$bigFileName = "/Users/yourLocalPath/yourFileName"; // Specify the path of the large file.
$partSize = 5 * 1024 * 1024; // Set the part size in bytes. In this example, the part size is set to 5 MB.
$fileSize = filesize($bigFileName); // Obtain the file size.
$partsNum = intdiv($fileSize, $partSize) + intval(1); // Calculate the number of parts.
$parts = []; // Used to store the upload result of each part.
$i = 1; // The part number starts from 1.
$file = new \GuzzleHttp\Psr7\LazyOpenStream($bigFileName, 'rb'); // Open the file stream.
while ($i <= $partsNum) {
// Upload a single part.
$partResult = $client->uploadPart(
new Oss\Models\UploadPartRequest(
bucket: $bucket,
key: $key,
partNumber: $i, // The current part number.
uploadId: $initResult->uploadId, // The upload ID returned by the initiated upload task.
contentLength: null, // Optional: The content length of the part.
contentMd5: null, // Optional: The MD5 hash of the part content for validation.
trafficLimit: null, // Optional: The traffic limit.
requestPayer: null, // Optional: The requester pays for the request.
body: new \GuzzleHttp\Psr7\LimitStream($file, $partSize, ($i - 1) * $partSize) // Read the data of the current part.
)
);
// Save the part upload result.
$part = new Oss\Models\UploadPart(
partNumber: $i, // The part number.
etag: $partResult->etag // The ETag value returned after the part is uploaded.
);
array_push($parts, $part); // Save the upload result of the current part to the part list.
$i++; // Increment the part number to process the next part.
}
// Complete the multipart upload task.
$comResult = $client->completeMultipartUpload(
new Oss\Models\CompleteMultipartUploadRequest(
bucket: $bucket,
key: $key,
uploadId: $initResult->uploadId, // The upload ID returned by the initiated upload task.
acl: null, // Optional: Set the access control list (ACL) of the object.
completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
parts: $parts // Submit the upload results of all parts.
)
)
);
// Print the result of the completed multipart upload.
printf(
'status code:' . $comResult->statusCode . PHP_EOL . // The HTTP status code. For example, 200 indicates that the request is successful.
'request id:' . $comResult->requestId . PHP_EOL . // The request ID, which is used to debug or track requests.
'complete multipart upload result:' . var_export($comResult, true) . PHP_EOL // The detailed result after the multipart upload is complete.
);
Cenários comuns
Execute um multipart upload e configure um callback de upload
Referências
Para obter o código de exemplo completo para multipart upload, consulte o exemplo no GitHub.