All Products
Search
Document Center

Object Storage Service:Simple upload (PHP SDK V2)

Last Updated:Mar 20, 2026

Use the putObject method to upload an object to a bucket in a single HTTP request. Simple upload works for files, strings, byte arrays, and network streams.

Prerequisites

Before you begin, make sure you have:

The sample code uses cn-hangzhou as the region ID and connects to the public endpoint by default. To access OSS from another Alibaba Cloud service in the same region, use an internal endpoint instead. For details, see Regions and endpoints.

Upload an object

All upload scenarios use PutObjectRequest and putObject. The only difference between uploading a local file, a string, a byte array, or a network stream is how you set $request->body.

The following example uploads a local file.

<?php

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

use AlibabaCloud\Oss\V2 as Oss;

// Parse command-line arguments: --region and --bucket and --key and --file are required; --endpoint is optional
$optsdesc = [
    "region"   => ['help' => 'The region where the bucket is located.', 'required' => true],
    "endpoint" => ['help' => 'The endpoint for accessing OSS.',          'required' => false],
    "bucket"   => ['help' => 'The bucket name.',                         'required' => true],
    "key"      => ['help' => 'The object key.',                          'required' => true],
    "file"     => ['help' => 'Local path of the file to upload.',        'required' => true],
];

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

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

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

// 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);

// Open the local file and wrap it in a stream
if (!file_exists($file)) {
    echo "Error: File not found: $file" . PHP_EOL;
    exit(1);
}
$body = Oss\Utils::streamFor(fopen($file, 'r'));

// Build the upload request
$request       = new Oss\Models\PutObjectRequest(bucket: $bucket, key: $key);
$request->body = $body;

// Upload the object
$result = $client->putObject($request);

printf(
    "status code: %s\nrequest ID:  %s\nETag:        %s\n",
    $result->statusCode,  // 200 indicates success
    $result->requestId,   // use this ID to debug or trace the request
    $result->etag         // unique identifier for the uploaded object
);

Upload other data types

To upload a string, byte array, or network stream, replace the $request->body assignment:

// Upload a string
$request->body = Oss\Utils::streamFor('Hello OSS');

// Upload a byte array (ASCII for 'Hello OSS')
$dataBytes     = [72, 101, 108, 108, 111, 32, 79, 83, 83];
$request->body = Oss\Utils::streamFor(implode(array_map('chr', $dataBytes)));

// Upload the response body from a URL
$request->body = Oss\Utils::streamFor(file_get_contents('https://www.aliyun.com/'));

Oss\Utils::streamFor() accepts any string or resource, so you can pass a file handle, a raw string, or the output of file_get_contents().

Track upload progress

Set $request->progressFn to a callback function that receives three parameters on every progress update:

ParameterTypeDescription
$incrementintBytes uploaded in this update
$transferredintTotal bytes uploaded so far
$totalintTotal size of the data being uploaded
<?php

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

use AlibabaCloud\Oss\V2 as Oss;

$optsdesc = [
    "region"   => ['help' => 'The region where the bucket is located.', 'required' => true],
    "endpoint" => ['help' => 'The endpoint for accessing OSS.',          'required' => false],
    "bucket"   => ['help' => 'The bucket name.',                         'required' => true],
    "key"      => ['help' => 'The object key.',                          'required' => true],
];

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

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

$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

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

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

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

$request       = new Oss\Models\PutObjectRequest($options["bucket"], $options["key"]);
$request->body = Oss\Utils::streamFor('Hello OSS');

// The progress callback fires on each data chunk sent
$request->progressFn = function (int $increment, int $transferred, int $total) {
    echo "Uploaded this chunk: {$increment} bytes" . PHP_EOL;
    echo "Total uploaded:      {$transferred} bytes" . PHP_EOL;
    echo "Object total size:   {$total} bytes" . PHP_EOL;
    echo str_repeat('-', 40) . PHP_EOL;
};

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

printf(
    "status code: %s\nrequest ID:  %s\nETag:        %s\n",
    $result->statusCode,
    $result->requestId,
    $result->etag
);

Trigger a callback after upload

OSS can send an HTTP callback to your application server after a successful upload. Include the callback parameters in the PutObjectRequest to enable this.

<?php

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

use AlibabaCloud\Oss\V2 as Oss;

$optsdesc = [
    "region"   => ['help' => 'The region where the bucket is located.', 'required' => true],
    "endpoint" => ['help' => 'The endpoint for accessing OSS.',          'required' => false],
    "bucket"   => ['help' => 'The bucket name.',                         'required' => true],
    "key"      => ['help' => 'The object key.',                          'required' => true],
];

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

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

$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

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

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

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

// Callback configuration: base64-encoded JSON
// Replace <your-callback-url> and <your-callback-host> with your server's values
$callback = base64_encode(json_encode([
    'callbackUrl'      => '<your-callback-url>',   // URL that OSS POSTs the callback to
    'callbackHost'     => '<your-callback-host>',  // Host header value in the callback request
    'callbackBody'     => 'bucket=${bucket}&object=${object}&etag=${etag}&size=${size}'
                        . '&mimeType=${mimeType}'
                        . '&imageInfo.height=${imageInfo.height}'
                        . '&imageInfo.width=${imageInfo.width}'
                        . '&imageInfo.format=${imageInfo.format}'
                        . '&my_var1=${x:var1}&my_var2=${x:var2}',
    'callbackBodyType' => 'application/x-www-form-urlencoded',
]));

// Custom variables are passed through the callback body as ${x:var_name}
$callbackVar = base64_encode(json_encode([
    'x:var1' => 'value1',
    'x:var2' => 'value2',
]));

$request              = new Oss\Models\PutObjectRequest(bucket: $options["bucket"], key: $options["key"]);
$request->callback    = $callback;
$request->callbackVar = $callbackVar;

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

printf(
    "status code:     %s\nrequest ID:      %s\ncallback result: %s\n",
    $result->statusCode,
    $result->requestId,
    var_export($result->callbackResult, true)  // contains the response body from your callback server
);

Callback parameters

ParameterTypeRequiredDescription
callbackUrlstringYesURL that OSS sends the POST request to after the upload completes
callbackHoststringNoValue of the Host header in the callback request
callbackBodystringYesTemplate for the callback request body; supports ${variable} placeholders
callbackBodyTypestringNoContent type of the callback body; defaults to application/x-www-form-urlencoded

Custom variables must use the x: prefix (for example, x:var1) and are referenced in callbackBody as ${x:var1}.

What's next

For the complete sample code, see GitHub example.