Append upload lets you add content to the end of an existing object incrementally — suited for use cases like log collection, streaming data writes, and any workflow where content is generated in chunks over time. This topic shows how to perform append upload using the OSS SDK for PHP V2.
For the complete runnable example, see the GitHub sample.
Prerequisites
Before you begin, make sure you have:
An OSS bucket
The
oss:PutObjectpermission. For details, see Attach a custom policy to a RAM userAccess credentials configured in environment variables. For details, see Configure access credentials
How it works
When you call AppendObject:
If the target object does not exist, OSS creates an appendable object and writes the content starting at position 0.
If the target object exists and is appendable, OSS appends the content at the position you specify. The position must equal the current length of the object; otherwise, OSS returns a
PositionNotEqualToLengtherror.If the target object exists but is not appendable (for example, it was uploaded using simple upload), OSS returns an
ObjectNotAppendableerror.
Each successful response includes a nextPosition field. Pass this value as the position parameter in your next AppendObject call.
Usage notes
The sample code uses region ID
cn-hangzhou(China (Hangzhou)) with a public endpoint. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint. For supported regions and endpoints, see Regions and endpoints.Access credentials are read from environment variables at runtime.
Append content to an object
First append
Set position to 0 for the first append. OSS creates the appendable object if it does not already exist.
<?php
// Load the SDK autoloader.
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// Define and parse command-line parameters.
$optsdesc = [
"region" => ['help' => 'The region where the bucket is located.', 'required' => true],
"endpoint" => ['help' => 'The endpoint for accessing 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])) {
echo "Error: --$key is required. " . $value['help'] . PHP_EOL;
exit(1);
}
}
$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];
// Load credentials from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// Configure the SDK client.
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);
if (isset($options["endpoint"])) {
$cfg->setEndpoint($options["endpoint"]);
}
$client = new Oss\Client($cfg);
// First append: position must be 0.
$data = 'Hello Append Object';
$request = new Oss\Models\AppendObjectRequest(bucket: $bucket, key: $key);
$request->body = Oss\Utils::streamFor($data);
$request->position = 0;
$result = $client->appendObject($request);
printf(
"status code: %s\n" .
"request id: %s\n" .
"next append position: %s\n",
$result->statusCode,
$result->requestId,
$result->nextPosition // Use this value as the position for the next append.
);Subsequent appends
Pass the nextPosition value from the previous response as the position for each subsequent call.
// Use the nextPosition returned by the previous AppendObject call.
$nextPosition = $result->nextPosition;
$moreData = 'More content to append';
$nextRequest = new Oss\Models\AppendObjectRequest(bucket: $bucket, key: $key);
$nextRequest->body = Oss\Utils::streamFor($moreData);
$nextRequest->position = $nextPosition;
$nextResult = $client->appendObject($nextRequest);
printf(
"status code: %s\n" .
"request id: %s\n" .
"next append position: %s\n",
$nextResult->statusCode,
$nextResult->requestId,
$nextResult->nextPosition
);If thepositionvalue does not match the current object length, OSS returnsPositionNotEqualToLength. Always use thenextPositionfrom the latest successful response to keep the position in sync.