版本控制

通过媒体存储提供的版本控制,您可以在一个桶中保留多个对象版本。例如,image.jpg(版本1)和image.jpg(版本2)。如果您希望防止自己意外覆盖和删除版本,或存档对象,以便您可以检索早期版本的对象,您可以开启版本控制功能。

您必须在您的存储桶上显式启用版本控制。默认情况下,版本控制处于禁用状态。无论您是否已启用版本控制,您的存储桶中的每个对象都具有版本 ID。如果未启用版本控制,则版本 ID 值被设置为空。如果已启用版本控制,则对象会被指定唯一版本 ID 值。在存储桶上启用版本控制时,该存储桶中的现有对象(如果有)不会发生更改:版本ID(空)、内容和权限保持为相同。

您可以使用 putBucketVersioning 接口开启版本控制,以下代码展示如何开启版本控制:

$bucket = '<your-bucket-name>';
//启用版本控制
$s3->putBucketVersioning([
    'Bucket' => $bucket,
    'VersioningConfiguration' => [
        'Status' => 'Enabled',
    ],
]);

在开启版本控制功能后,上传同名对象将不再删除旧对象,而是添加一个新的对象。普通的删除操作也不会将对象彻底删除,而是添加一个 Delete Marker 作为标识。容器开启版本控制功能之后,无法再关闭该功能,只能暂停。

以下代码展示如何暂停版本控制:

$bucket = '<your-bucket-name>';
//暂停版本控制
$s3->putBucketVersioning([
    'Bucket' => $bucket,
    'VersioningConfiguration' => [
        'Status' => 'Suspended',
    ],
]);

获取指定版本对象

您可以在 GetObject 接口中指定版本ID获取指定版本对象:

//获取指定版本对象时需要指定其版本号
$bucket = '<your-bucket-name>';
$keyname = '<your-object-key>';
$file_Path = '<your-file-path>';
$versionId = '<your-version-id>';
try {
    // 保存对象到指定路径
    $result = $s3Client->getObject(array(
        'Bucket' => $bucket,
        'Key' => $keyname,
        'SaveAs' => $file_Path,
        'VersionId' => $versionId, //指定对象版本号
    ));
} catch (S3Exception $e) {
    echo $e->getMessage() . "\n";
}

列举对象版本

如果桶开启了版本控制,您可以使用 listObjectVersions 接口列举对象的版本,每次list操作最多返回1000个分片上传事件,简单列举对象版本代码如下:

$bucket = '<your-bucket-name>';
$versions = $s3->listObjectVersions(['Bucket' => $bucket])
    ->search('Versions');
foreach ($versions as $version){
    echo "Key: " . $version['Key'] . "\n";
    echo "VersionId: " . $version['VersionId'] . "\n";
}

如果 list 大于1000,则可以使用 Paginator 接口列举所有对象版本。列举所有对象版本示例代码如下:

$bucket = '<your-bucket-name>';
$results = $s3->getPaginator('ListObjectVersions', ['Bucket' => $bucket]);
foreach ($results as $result){
    foreach ($result['Versions'] as $version){
        echo "Key: " . $version['Key'] . "\n";
        echo "VersionId: " . $version['VersionId'] . "\n";
    }
}

删除对象版本

如果桶开启了版本控制,您可以在 deleteObject 接口删除指定对象的版本,以下代码展示如何删除单个对象版本:

$bucket = '<your-bucket-name>';
$keyname = '<your-object-key>';
$versionId = '<your-version-id>';
$result = $s3->deleteObject([
    'Bucket' => $bucket,
    'Key' => $keyname,
    'VersionId' => $versionId,  //指定对象版本
]);

默认情况下,如果开启了版本控制,使用 deleteObject 删除对象不会将该对象彻底删除,而是添加一个 Delete Marker 作为标识。如果您确定不再需要某个对象,则需要删除该对象的所有版本,才可以将其彻底删除。对象的版本号可以通过 listVersions 接口获取。您可以通过 deleteVersion 接口删除单个对象版本,也可以通过 deleteObjects 接口在 KeyVersion 中指定 versionID 的方式删除多个对象版本,示例代码如下:

$bucket = '<your-bucket-name>';
$result = $s3-$ObjectVersions = [
    [
        'Key' => '<your-object-key1>',
        'VersionId' => '<your-verison-id1>',
    ],
    [
        'Key' => '<your-object-key2>',
        'VersionId' => '<your-verison-id2>',
    ],
    [
        'Key' => '<your-object-key3>',
        'VersionId' => '<your-verison-id3>',
    ]
];
$result = $s3->deleteObjects([
    'Bucket' => $bucket,
    'Delete' => [
        'Objects' => $ObjectVersions
    ],
]);
echo "The following objects were deleted successfully:" . "\n";
foreach ($result['Deleted'] as $object) {
    echo "Key: {$object['Key']}, VersionId: {$object['VersionId']}" . "\n";
}