Copy an object within a bucket or from a source bucket to a destination bucket in the same region. Use this operation to:
Create additional copies of objects.
Rename objects by copying them and then deleting the originals.
Change object metadata without re-uploading the object.
Move data between buckets in the same region.
Prerequisites
Before you begin, make sure that you have:
An
OssClientinstance. See Create an OSSClient instance.The following permissions on the RAM user performing the copy:
oss:GetObjecton the source objectoss:PutObjectandoss:GetObjecton the destination bucketFor details, see Common examples of RAM policies.
Usage notes
The source bucket and destination bucket must be in the same region. Cross-region copies are not supported. For example, you cannot copy from a bucket in China (Hangzhou) to a bucket in China (Qingdao).
If either the source or destination bucket has a retention policy configured, the copy fails with:
The object you specified is immutable.The examples in this topic use the public endpoint for China (Hangzhou):
oss-cn-hangzhou.aliyuncs.com. To access OSS from other Alibaba Cloud services in the same region, use the internal endpoint.
Choose a copy method
| Object size | Method | SDK call |
|---|---|---|
| Smaller than 1 GB | Simple copy | copyObject |
| Larger than 1 GB | Multipart copy | initiateMultipartUpload → uploadPartCopy → completeMultipartUpload |
Copy a small file
Use $ossClient->copyObject for objects 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;
// Read credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this example.
$provider = new EnvironmentVariableCredentialsProvider();
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Replace with your endpoint.
$from_bucket = "srcexamplebucket"; // Source bucket name.
$from_object = "srcdir/exampleobject.txt"; // Source object path (no bucket name).
$to_bucket = "destexamplebucket"; // Destination bucket name.
$to_object = "destdir/exampleobject.txt"; // Destination object path (no bucket name).
try {
$config = [
"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");Optional request headers
Pass optional headers in the $options array to control copy behavior:
| Header | Description |
|---|---|
x-oss-forbid-overwrite | Set to true to prevent overwriting a destination object with the same name. |
x-oss-copy-source-if-match | Copy only if the source object ETag matches the specified value. Returns 200 OK on match. |
x-oss-copy-source-if-none-match | Copy only if the source object ETag does not match the specified value. Returns 200 OK on mismatch. |
x-oss-copy-source-if-unmodified-since | Copy only if the source object has not been modified since the specified time. |
x-oss-copy-source-if-modified-since | Copy only if the source object has been modified since the specified time. |
x-oss-metadata-directive | How to set metadata on the destination object. Set to COPY to copy metadata from the source. |
x-oss-server-side-encryption | Server-side encryption algorithm for the destination object (for example, KMS). |
x-oss-server-side-encryption-key-id | Customer master key (CMK) ID managed by Key Management Service (KMS). Valid only when x-oss-server-side-encryption is set to KMS. |
x-oss-object-acl | Access permissions for the destination object (for example, private). |
x-oss-storage-class | Storage class for the destination object (for example, Standard). |
x-oss-tagging | Tags for the destination object. Specify multiple tags as key-value pairs: k1=v1&k2=v2. |
x-oss-tagging-directive | How to set tags on the destination object. Set to COPY to copy tags from the source. |
Example with optional headers:
$options = [
'headers' => [
'x-oss-forbid-overwrite' => 'true',
'x-oss-metadata-directive' => 'COPY',
'x-oss-object-acl' => 'private',
'x-oss-storage-class' => 'Standard',
],
];
$ossClient->copyObject($from_bucket, $from_object, $to_bucket, $to_object, $options);Copy a large file
For objects larger than 1 GB, use multipart copy: split the object into parts and copy each part with uploadPartCopy. All parts except the last must be larger than 100 KB.
Steps:
Call
$ossClient->initiateMultipartUploadto initialize the multipart copy task and get an upload ID.Call
$ossClient->uploadPartCopyfor each part. All parts except the last must be larger than 100 KB.Call
$ossClient->completeMultipartUploadto commit the task.
<?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;
// Read credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this example.
$provider = new EnvironmentVariableCredentialsProvider();
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // Replace with your endpoint.
$from_bucket = "yourSrcBucketName";
$from_object = "yourSrcObjectName";
$to_bucket = "yourDestBucketName";
$to_object = "yourDestObjectName";
$part_size = 256 * 1024 * 1024; // 256 MB per part. Adjust as needed.
try {
$config = [
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region" => "cn-hangzhou",
];
$ossClient = new OssClient($config);
// Get the source object size.
$objectMeta = $ossClient->getObjectMeta($from_bucket, $from_object);
$length = $objectMeta['content-length'] + 0;
// Step 1: Initialize the multipart copy task.
$upload_id = $ossClient->initiateMultipartUpload($to_bucket, $to_object);
// Step 2: Copy parts.
$pieces = $ossClient->generateMultiuploadParts($length, $part_size);
$response_upload_part = [];
$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 = [
'start' => $from_pos,
'end' => $to_pos,
'headers' => [
// 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++;
}
// Step 3: Commit the multipart copy task.
$upload_parts = [];
foreach ($response_upload_part as $i => $etag) {
$upload_parts[] = [
'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");What's next
For the complete sample code, see GitHub.
For the API reference for simple copy, see CopyObject.
For the API reference for multipart copy, see UploadPartCopy.