All Products
Search
Document Center

Object Storage Service:File copy manager (PHP SDK V2)

Last Updated:Mar 20, 2026

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:

APIApplies when
CopyObjectObject is smaller than 5 GB
UploadPartCopyObject 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:

PlaceholderDescriptionExample
<region>Region where the bucket is locatedcn-hangzhou
<destination-bucket>Name of the destination bucketmy-bucket
<destination-key>Name of the destination objectdest/photo.jpg
<source-bucket>Name of the source bucketmy-bucket
<source-key>Name of the source objectsrc/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

OptionTypeDefaultDescription
part_sizeint64 MiBPart size for multipart copy
parallel_numint3Concurrency limit for a single copy call (not global)
multipart_copy_thresholdint200 MiBObject size above which multipart copy is used
leave_parts_on_errorboolfalseRetain uploaded parts if the copy fails
disable_shallow_copyboolfalseDisable shallow copy behavior

CopyObjectRequest parameters

ParameterTypeDescription
bucketstringDestination bucket name
keystringDestination object name
sourceBucketstringSource bucket name
sourceKeystringSource object name
metadataDirectivestringCopy (default) — copies source metadata; REPLACE — uses metadata from the request
taggingDirectivestringCopy (default) — copies source tags; REPLACE — uses tags from the request
taggingstringTags to apply when taggingDirective is REPLACE. Format: TagA=A&TagB=B
forbidOverwritestringWhether 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