Updated on 2026-08-03 GMT+08:00

Restoring Archive Objects in Batches

If you have any questions during development, post them on the Issues page of GitHub. For details about parameters and usage of each API, see API Reference.

Sample Code

This example restores Archive objects in batches. Archive objects must be restored before they can be accessed. The restoration usually takes 3 to 5 hours in standard mode. The restoration of Deep Archive objects usually takes 12 to 48 hours in batch mode. The restoration time varies depending on the restoration options.

<?php
// Import the dependency library.
require 'vendor/autoload.php';
// Import the SDK code library during source code installation.
// require 'obs-autoloader.php';
// Declare the namespace.
use Obs\ObsClient;
// Create an instance of ObsClient.
$obsClient = new ObsClient ( [
      // Obtain an AK/SK pair using environment variables or import the AK/SK pair in other ways. Using hard coding may result in leakage.
      //Obtain an AK/SK pair on the management console. For details, see https://support.huaweicloud.com/intl/en-us/usermanual-ca/ca_01_0003.html.
      'key' => getenv('ACCESS_KEY_ID'),
      'secret' => getenv('SECRET_ACCESS_KEY'),
      // Enter the endpoint corresponding to the bucket. CN-Hong Kong is used here as an example. Replace it with the one currently in use.
       'endpoint' => "obs.ap-southeast-1.myhuaweicloud.com",
      'signature' => 'obs'
] );

$bucketName = 'bucketname';
$concurrency = 5;
// Days specifies the number of days during which the restored objects can be accessed. For the Archive and Deep Archive objects, the minimum value is 1, in days.
$restoreDays = 30;

// List all objects in the bucket and filter out the objects in the Archive or Deep Archive storage class.
// To restore only objects with a specified prefix, set the Prefix parameter in listObjects.
$isTruncated = true;
$marker = null;
$archiveObjects = [];

while ($isTruncated) {
       $resp = $obsClient->listObjects ( [
              'Bucket' => $bucketName,
              'Marker' => $marker
       ] );
       if (!empty($resp['Contents'])) {
              foreach ($resp['Contents'] as $content) {
                     $storageClass = isset($content['StorageClass']) ? $content['StorageClass'] : 'STANDARD';
                     if ($storageClass === 'COLD' || $storageClass === 'ARCHIVE' || $storageClass === 'DEEP_ARCHIVE') {
                            $archiveObjects[] = ['Key' => $content['Key'], 'StorageClass' => $storageClass];
                     }
              }
       }
       $isTruncated = $resp['IsTruncated'];
       $marker = $resp['NextMarker'];
}
printf("Found %d archive objects to restore\n\n", count($archiveObjects));

//Restore Archive objects concurrently.
// In the production environment, you are advised to add a retry mechanism to prevent incomplete restoration caused by network fluctuation or temporary faults.

$successCount = 0;
$failCount = 0;

$promiseGenerator = function () use ($obsClient, $bucketName, $archiveObjects, $restoreDays, &$successCount, &$failCount) {
       foreach ($archiveObjects as $object) {
              // Before restoration, you are advised to use getObjectMetadata to check the Restore header of objects and determine the restoration status.
              // If objects have been restored and are still within the validity period, skip the restoration or extend the validity period.
              // Select the restoration option based on the storage class. For Archive objects, use standard restoration. For Deep Archive objects, use batch restoration.
              $tier = ($object['StorageClass'] === 'DEEP_ARCHIVE')
                     ? ObsClient::RestoreTierBulk
                     : ObsClient::RestoreTierStandard;
              yield $obsClient->restoreObjectAsync ( [
                     'Bucket' => $bucketName,
                     'Key' => $object['Key'],
                     'Days' => $restoreDays,
                     'Tier' => $tier
              ], function ($exception, $resp) use ($object, &$successCount, &$failCount) {
                     if ($exception === null) {
                            printf ( "Key:%s, StorageClass:%s, RequestId:%s\n", $object['Key'], $object['StorageClass'], $resp['RequestId'] );
                            $successCount++;
                     } else {
                            printf ( "RestoreFailed: Key:%s, Status:%d, Message:%s\n", $object['Key'], $exception->getStatusCode(), $exception->getExceptionMessage() );
                            $failCount++;
                     }
              } );
       }
};

$eachPromise = new EachPromise($promiseGenerator(), [
       'concurrency' => $concurrency
]);

$eachPromise->promise()->wait();

printf("\nResult: success=%d, fail=%d\n", $successCount, $failCount);

To extend the validity period of the Archive data restored, you can repeatedly restore the data, but you will be billed for each restoration. After a second restore, the validity period of Standard object copies will be prolonged, and you need to pay for storing these copies during the prolonged period.