Upload a file (OSS SDK for PHP V2)

Updated at:

OSS SDK for PHP V2 supports three upload methods for versioned buckets: simple upload, append upload, and multipart upload. Each method interacts with versioning differently — choose the one that fits your file size and access pattern.

MethodUse whenVersioning behavior
Simple uploadFiles of any size, single-request writesOSS generates a unique version ID per upload
Append uploadLog files or data streams built incrementallyAppending to an appendable object does not create a new version
Multipart uploadLarge files where reliability mattersOSS assigns a version ID when the upload is completed

Prerequisites

Before you begin, make sure you have:

  • A versioning-enabled or versioning-suspended OSS bucket

  • The oss:PutObject permission. For details, see Attach a custom policy to a RAM user

  • OSS SDK for PHP V2 installed, with dependencies loaded via Composer

The sample code uses the China (Hangzhou) region (cn-hangzhou) with a public endpoint. To access OSS from another Alibaba Cloud service in the same region, use an internal endpoint instead. For region-to-endpoint mappings, see Regions and endpoints.

Simple upload

PutObject uploads an object in a single request.

Versioning behavior:

  • In a versioning-enabled bucket, OSS generates a unique version ID and returns it in the x-oss-version-id response header.

  • In a versioning-suspended bucket, the version ID is null. Uploading an object with the same key as an existing object overwrites it, leaving only a single version with a null version ID.

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Describe command-line parameters.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located', 'required' => True],
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS', 'required' => False],
    "bucket" => ['help' => 'The name of the bucket', 'required' => True],
    "key" => ['help' => 'The name of the object', 'required' => True],
];

$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

$options = getopt("", $longopts);

foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help";
        exit(1);
    }
}

$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];

// Load credentials from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);

if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

$client = new Oss\Client($cfg);

$data = 'Hello OSS';

$request = new Oss\Models\PutObjectRequest(
    bucket: $bucket,
    key: $key,
);
$request->body = Oss\Utils::streamFor($data);

$result = $client->putObject($request);

printf(
    'status code: ' . $result->statusCode . PHP_EOL .
    'request ID: ' . $result->requestId . PHP_EOL .
    'ETag: ' . $result->etag . PHP_EOL
);

Append upload

AppendObject appends data to an existing appendable object. This method suits log files or other data streams where content is added incrementally.

Versioning behavior:

  • AppendObject can only be performed on the current version of an appendable object.

  • Appending to an appendable object does not create a previous version.

  • Calling PutObject or DeleteObject on an appendable object saves it as a previous version that can no longer be appended to.

  • AppendObject cannot be performed on non-appendable objects such as normal objects or delete markers.

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Describe command-line parameters.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located', 'required' => True],
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS', 'required' => False],
    "bucket" => ['help' => 'The name of the bucket', 'required' => True],
    "key" => ['help' => 'The name of the object', 'required' => True],
];

$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

$options = getopt("", $longopts);

foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help";
        exit(1);
    }
}

$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];

// Load credentials from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);

if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

$client = new Oss\Client($cfg);

$data = 'Hello Append Object';

$request = new Oss\Models\AppendObjectRequest(bucket: $bucket, key: $key);
$request->body = Oss\Utils::streamFor($data);

// Set position to 0 to start from the beginning of the object.
$request->position = 0;

$result = $client->appendObject($request);

printf(
    'status code: ' . $result->statusCode . PHP_EOL .
    'request ID: ' . $result->requestId . PHP_EOL
);

Multipart upload

Multipart upload splits a large file into parts, uploads them in sequence, and combines them into a complete object with CompleteMultipartUpload.

Versioning behavior: OSS generates a unique version ID for the object when CompleteMultipartUpload is called successfully. The version ID is returned in the x-oss-version-id response header.

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Describe command-line parameters.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True],
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False],
    "bucket" => ['help' => 'The name of the bucket', 'required' => True],
    "key" => ['help' => 'The name of the object', 'required' => True],
];

$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

$options = getopt("", $longopts);

foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1);
    }
}

$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];

// Load credentials from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);

if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

$client = new Oss\Client($cfg);

// Step 1: Initiate the multipart upload and get the upload ID.
$request = new Oss\Models\InitiateMultipartUploadRequest(bucket: $bucket, key: $key);
$result = $client->initiateMultipartUpload($request);
$uploadId = $result->uploadId;

// Step 2: Upload parts. Part numbers start from 1.
$bigFileName = "/Users/localpath/yourfilename"; // Replace with the path of your local file.
$partSize = 1 * 1024 * 1024;                    // Part size in bytes. This example uses 1 MB.

$file = fopen($bigFileName, 'r');
$parts = [];

if ($file) {
    $i = 1;
    while (!feof($file)) {
        $chunk = fread($file, $partSize);
        $partResult = $client->uploadPart(
            new Oss\Models\UploadPartRequest(
                bucket: $bucket,
                key: $key,
                partNumber: $i,
                uploadId: $uploadId,
                contentLength: null,
                contentMd5: null,
                trafficLimit: null,
                requestPayer: null,
                body: Oss\Utils::streamFor(resource: $chunk)
            )
        );
        $parts[] = new Oss\Models\UploadPart(
            partNumber: $i,
            etag: $partResult->etag,
        );
        $i++;
    }
    fclose($file);
}

// Step 3: Complete the multipart upload.
// OSS assigns a version ID to the object at this point.
$comResult = $client->completeMultipartUpload(
    new Oss\Models\CompleteMultipartUploadRequest(
        bucket: $bucket,
        key: $key,
        uploadId: $uploadId,
        acl: null,
        completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
            parts: $parts
        ),
    )
);

printf(
    'status code: ' . $comResult->statusCode . PHP_EOL .
    'request ID: ' . $comResult->requestId . PHP_EOL .
    'complete multipart upload result: ' . var_export($comResult, true) . PHP_EOL
);

What's next