This topic describes how to copy an object from a source bucket to the same or a different destination bucket in the same region.
Usage notes
In this topic, the public endpoint of the China (Hangzhou) region is used. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint. For details about supported regions and endpoints, see Regions and endpoints.
In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Create an OSSClient instance.
When a Resource Access Management (RAM) user performs a copy operation, the RAM user must have the
oss:GetObjectpermission on the source object. The user must also have theoss:PutObjectandoss:GetObjectpermissions on the destination bucket. For more information about how to grant custom policies to a RAM user, see Common examples of RAM policies.Make sure that no retention policies are configured for the source bucket and the destination bucket. Otherwise, the error message The object you specified is immutable. is returned.
The source bucket and destination bucket must be in the same region. For example, objects cannot be copied from a bucket located in the China (Hangzhou) region to another bucket located in the China (Qingdao) region.
Copy a small file
The following sample code shows how to use the $ossClient->copyObject method to copy an object smaller than 1 GB:
<?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();
// The endpoint of the China (Hangzhou) region is used in this example. Replace the value with the actual endpoint.
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the source bucket. Example: srcexamplebucket.
$from_bucket = "srcexamplebucket";
// Specify the full path of the source object. The full path cannot contain the bucket name. Example: srcdir/exampleobject.txt.
$from_object = "srcdir/exampleobject.txt";
// Specify the name of the destination bucket that is in the same region as the source bucket. Example: destexamplebucket.
// If you copy an object within the same bucket, make sure that the source and destination bucket names are the same.
$to_bucket = "destexamplebucket";
// Specify the full path of the destination object. The full path cannot contain the bucket name. Example: destdir/exampleobject.txt.
$to_object = "destdir/exampleobject.txt";
$options = array(
'headers'=>array(
// Specify whether to overwrite a destination object that has the same name. In this example, this parameter is set to true to prevent overwriting.
// 'x-oss-forbid-overwrite' => 'true',
// If the ETag of the source object matches the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-match' => '5B3C1A2E053D763E1B002CC****',
// If the ETag of the source object does not match the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-none-match' => '5B3C1A2E053D763E1B002CC****',
// If the specified time is the same as or later than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-unmodified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// If the specified time is earlier than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-modified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// Specify how to configure metadata for the destination object. In this example, this parameter is set to COPY to copy the metadata from the source object to the destination object.
// 'x-oss-metadata-directive' => 'COPY',
// Specify the server-side encryption algorithm that OSS uses to create the destination object.
// 'x-oss-server-side-encryption' => 'KMS',
// The customer master key (CMK) managed by KMS. This parameter is valid only when x-oss-server-side-encryption is set to KMS.
// 'x-oss-server-side-encryption-key-id' => '9468da86-3509-4f8d-a61e-6eab****',
// Specify the access permissions for the destination object. In this example, this parameter is set to private. This means only the object owner and authorized users have read and write permissions. Other users cannot access the object.
// 'x-oss-object-acl' => 'private',
// Specify the storage class of the object. In this example, this parameter is set to Standard.
// 'x-oss-storage-class' => 'Standard',
// Specify the tags for the object. You can specify multiple tags.
// 'x-oss-tagging' => 'k1=v1&k2=v2&k3=v3',
// Specify how to configure tags for the destination object. In this example, this parameter is set to COPY to copy the tags from the source object to the destination object.
// 'x-oss-tagging-directive' => 'COPY',
),
);
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$ossClient->copyObject($from_bucket, $from_object, $to_bucket, $to_object);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n"); Copy a large file
To copy an object whose size is larger than 1 GB, you must split the object into parts and sequentially copy the parts by using UploadPartCopy. To implement multipart copy, perform the following steps:
Call
$ossClient->initiateMultipartUploadto initialize a multipart copy task.Call
$ossClient->uploadPartCopyto copy parts. All parts except the last one must be larger than 100 KB.Call
$ossClient->completeMultipartUploadto commit the multipart copy task.
The following sample code shows how to perform a multipart copy:
<?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();
// The endpoint of the China (Hangzhou) region is used in this example. Replace the value with the actual endpoint.
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the source bucket.
$from_bucket = "yourSrcBucketName";
// Specify the full path of the source object. The full path cannot contain the bucket name. Example: srcdir/exampleobject.txt.
$from_object = "yourSrcObjectName";
// Specify the name of the destination bucket that is in the same region as the source bucket.
$to_bucket = "yourDestBucketName";
// Specify the full path of the destination object. The full path cannot contain the bucket name. Example: destdir/exampleobject.txt.
$to_object = 'yourDestObjectName';
// Set the part size in bytes as needed.
$part_size = 256*1024*1024;
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$objectMeta = $ossClient->getObjectMeta($from_bucket, $from_object);
$length = $objectMeta['content-length'] + 0;
// Initialize the multipart copy task.
$upload_id = $ossClient->initiateMultipartUpload($to_bucket, $to_object);
// Copy parts.
$pieces = $ossClient->generateMultiuploadParts($length, $part_size);
$response_upload_part = array();
$copyId = 1;
$upload_position = 0;
foreach ($pieces as $i => $piece) {
$from_pos = $upload_position + (integer)$piece['seekTo'];
$to_pos = (integer)$piece['length'] + $from_pos - 1;
$up_options = array(
'start' => $from_pos,
'end' => $to_pos,
'headers'=>array(
// If the ETag of the source object matches the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-match' => '5B3C1A2E053D763E1B002CC****',
// If the ETag of the source object does not match the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-none-match' => '5B3C1A2E053D763E1B002CC****',
// If the specified time is the same as or later than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-unmodified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// If the specified time is earlier than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-modified-since' => gmdate('2021-12-09T07:01:56.000Z'),
),
);
$response_upload_part[] = $ossClient->uploadPartCopy( $from_bucket, $from_object, $to_bucket, $to_object, $copyId, $upload_id, $up_options);
$copyId = $copyId + 1;
}
// Complete the multipart copy.
$upload_parts = array();
foreach ($response_upload_part as $i => $etag) {
$upload_parts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $etag,
);
}
$result = $ossClient->completeMultipartUpload($to_bucket, $to_object, $upload_id, $upload_parts);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");References
Copy a small file
For the complete sample code to copy a small file, see GitHub.
For more information about the API operation to copy a small file, see CopyObject.
Copy a large file
For the complete sample code to copy a large file, see GitHub.
For more information about the API operation to copy a large file, see UploadPartCopy.