The Copier class in OSS SDK for PHP V2 provides a single copy API that automatically selects between CopyObject and UploadPartCopy based on the object size—so you don't have to manage the two APIs separately.
Prerequisites
Before you begin, make sure you have:
Read permission on the source object
Read and write permissions on the destination bucket
AccessKey credentials configured as environment variables (see Configure access credentials for PHP)
Usage notes
Cross-region copy is not supported. The source and destination buckets must be in the same region.
If a retention policy is configured on either the source or destination bucket, the copy fails with:
The object you specified is immutable.The sample code in this topic uses the China (Hangzhou) region. If you access OSS from another Alibaba Cloud service within the same region, use an internal endpoint instead of a public endpoint. For details, see OSS regions and endpoints.
How it works
Copier wraps two underlying OSS APIs and picks the right one automatically:
| API | Applies when |
|---|---|
CopyObject | Object is smaller than 5 GB |
UploadPartCopy | Object is larger than 5 GB (multipart copy) |
When UploadPartCopy is used, the metadata directive (x-oss-metadata-directive) and tagging directive (x-oss-tagging-directive) parameters are not supported. Set metadata and tags explicitly in the request.
By default, Copier copies both the metadata and tags from the source object. Override this behavior by setting metadataDirective or taggingDirective to REPLACE in the request.
Copy an object
The following example copies an object from a source bucket to a destination bucket and replaces the metadata and tags with empty values.
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// Load credentials from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion('<region>'); // e.g., cn-hangzhou
$client = new Oss\Client($cfg);
// Create a Copier instance.
$copier = $client->newCopier();
$copyRequest = new Oss\Models\CopyObjectRequest(
bucket: '<destination-bucket>',
key: '<destination-key>',
sourceBucket: '<source-bucket>',
sourceKey: '<source-key>'
);
// REPLACE clears the source metadata/tags; omit these lines to copy them instead.
$copyRequest->metadataDirective = 'REPLACE';
$copyRequest->taggingDirective = 'REPLACE';
$result = $copier->copy(request: $copyRequest);
echo 'Status code: ' . $result->statusCode . PHP_EOL;
echo 'Request ID: ' . $result->requestId . PHP_EOL;Replace the following placeholders:
| Placeholder | Description | Example |
|---|---|---|
<region> | Region where the bucket is located | cn-hangzhou |
<destination-bucket> | Name of the destination bucket | my-bucket |
<destination-key> | Name of the destination object | dest/photo.jpg |
<source-bucket> | Name of the source bucket | my-bucket |
<source-key> | Name of the source object | src/photo.jpg |
Configure the Copier
Pass configuration options when creating a Copier instance (applies to all copy calls) or per individual call (overrides the instance-level config).
Instance-level config — applies to all calls on this Copier:
$copier = $client->newCopier(['part_size' => 100 * 1024 * 1024]);Per-call config — applies to a single copy operation:
$copier->copy(
new Oss\Models\CopyObjectRequest(
bucket: '<destination-bucket>',
key: '<destination-key>',
sourceBucket: '<source-bucket>',
sourceKey: '<source-key>',
),
args: ['part_size' => 100 * 1024 * 1024]
);Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
part_size | int | 64 MiB | Part size for multipart copy |
parallel_num | int | 3 | Concurrency limit for a single copy call (not global) |
multipart_copy_threshold | int | 200 MiB | Object size above which multipart copy is used |
leave_parts_on_error | bool | false | Retain uploaded parts if the copy fails |
disable_shallow_copy | bool | false | Disable shallow copy behavior |
CopyObjectRequest parameters
| Parameter | Type | Description |
|---|---|---|
bucket | string | Destination bucket name |
key | string | Destination object name |
sourceBucket | string | Source bucket name |
sourceKey | string | Source object name |
metadataDirective | string | Copy (default) — copies source metadata; REPLACE — uses metadata from the request |
taggingDirective | string | Copy (default) — copies source tags; REPLACE — uses tags from the request |
tagging | string | Tags to apply when taggingDirective is REPLACE. Format: TagA=A&TagB=B |
forbidOverwrite | string | Whether to overwrite an existing object with the same name in the destination bucket |
Set part size and concurrency
The following example configures a 1 MiB part size and a concurrency of 5 for a single copy call.
$result = $copier->copy(
request: $copyRequest,
args: [
'part_size' => 1 * 1024 * 1024, // 1 MiB per part
'parallel_num' => 5, // 5 concurrent part uploads
]
);
echo 'Status code: ' . $result->statusCode . PHP_EOL;
echo 'Request ID: ' . $result->requestId . PHP_EOL;What's next
For the complete runnable sample, see the GitHub sample.
To configure credentials, see Configure access credentials for PHP.
For OSS region and endpoint details, see OSS regions and endpoints.