All Products
Search
Document Center

Object Storage Service:Configure upload callbacks using OSS SDK for PHP 1.0

Last Updated:Mar 20, 2026

Upload callbacks let OSS notify your application server when an object upload completes. Include callback parameters in the upload request to enable this — no separate configuration step is required.

How it works

  1. Your client sends an upload request to OSS with callback parameters attached.

  2. OSS stores the object.

  3. OSS sends an HTTP POST request to your callback server URL with the fields you specified in callbackBody.

  4. Your callback server processes the request and returns a JSON response.

  5. OSS forwards that response to your client.

Upload callbacks work with both simple upload (putObject) and multipart upload (completeMultipartUpload). For multipart upload, attach the callback parameters in Step 3 (complete), not in Step 1 (initiate).

Prerequisites

Before you begin, make sure that you have:

  • An OSS bucket

  • The OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables set with valid access credentials

  • A publicly accessible callback server URL that can handle HTTP POST requests

Usage notes

  • The examples in this topic use the public endpoint for the China (Hangzhou) region. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint instead. For supported regions and endpoints, see Regions and endpoints.

  • The examples create an OSSClient instance using an OSS endpoint. To create an OSSClient instance using a custom domain name or Security Token Service (STS), see Create an OSSClient instance.

Callback parameters

All callback parameters are passed as a JSON string to OssClient::OSS_CALLBACK. Custom variables are passed separately to OssClient::OSS_CALLBACK_VAR.

ParameterRequiredDescription
callbackUrlYesThe URL of your callback server. OSS sends an HTTP POST request to this address after the upload completes. Example: https://oss-demo.aliyuncs.com:23450
callbackHostNoThe value of the Host header in the callback request. If omitted, OSS uses the host parsed from callbackUrl.
callbackBodyYesThe body of the callback request. Use system variables (e.g., ${bucket}, ${object}, ${size}) and custom variables (e.g., ${x:var1}) to include upload metadata.
callbackBodyTypeYesThe Content-Type of the callback request body. Use application/x-www-form-urlencoded for simple upload or application/json for multipart upload.

Custom variables are key-value pairs passed to OssClient::OSS_CALLBACK_VAR. Each key must start with x:. These values are available in callbackBody as ${x:key_name}.

System variables available in `callbackBody`:

VariableDescription
${bucket}Bucket name
${object}Object path
${etag}ETag of the uploaded object
${size}Object size in bytes
${mimeType}MIME type of the object
${imageInfo.height}Image height (for image objects)
${imageInfo.width}Image width (for image objects)
${imageInfo.format}Image format (for image objects)

Callback server requirements

OSS sends an HTTP POST request to your callback server URL after the upload completes. Your callback server must meet the following requirements:

  • Publicly accessible: The callback URL must be reachable from the internet.

  • Return valid JSON: The response body must be valid JSON. OSS forwards this JSON response to the client as-is.

  • Return HTTP 200: Return an HTTP 200 status code to indicate success. OSS treats other status codes as callback failures.

  • Respond promptly: If your callback server does not respond in time, OSS treats the callback as failed. Design your callback handler to respond quickly — offload any time-consuming processing to an asynchronous queue.

Configure a callback for simple upload

Attach callback parameters to a putObject call using OssClient::OSS_CALLBACK and OssClient::OSS_CALLBACK_VAR.

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;

// Load access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
$provider = new EnvironmentVariableCredentialsProvider();

// Replace with the endpoint of the region where your bucket is located.
// Example: https://oss-cn-hangzhou.aliyuncs.com
$endpoint = "yourEndpoint";

// Replace with your bucket name and object path.
$bucket = "examplebucket";
$object = "exampledir/exampleobject.txt";

$config = array(
    "provider"         => $provider,
    "endpoint"         => $endpoint,
    "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
    "region"           => "cn-hangzhou"
);
$ossClient = new OssClient($config);

// Define the callback. callbackBody uses form-urlencoded format for simple upload.
$callback =
    '{
        "callbackUrl":"yourCallbackServerUrl",
        "callbackHost":"yourCallbackServerHost",
        "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"
    }';

// Define custom variables. Keys must start with x:.
$var =
    '{
        "x:var1":"value1",
        "x:var2":"value2"
    }';

$options = array(
    OssClient::OSS_CALLBACK     => $callback,
    OssClient::OSS_CALLBACK_VAR => $var,
);

$result = $ossClient->putObject($bucket, $object, file_get_contents(__FILE__), $options);

// Print the callback server response body and the HTTP status code.
print_r($result['body']);
print_r($result['info']['http_code']);

Replace the following placeholders before running the code:

PlaceholderDescriptionExample
yourEndpointEndpoint of the region where your bucket is locatedhttps://oss-cn-hangzhou.aliyuncs.com
examplebucketBucket namemy-bucket
exampledir/exampleobject.txtFull object path, excluding the bucket nameuploads/photo.jpg
yourCallbackServerUrlPublicly accessible URL of your callback serverhttps://example.com/callback
yourCallbackServerHost(Optional) Host header value for the callback requestexample.com

What your callback server receives:

For simple upload with application/x-www-form-urlencoded, your server receives an HTTP POST request with a body similar to:

bucket=examplebucket&object=exampledir%2Fexampleobject.txt&etag=5B3C1A2E883EC0D921E4571E9B4F2C38&size=1024&mimeType=text%2Fplain&imageInfo.height=&imageInfo.width=&imageInfo.format=&my_var1=value1&my_var2=value2

Configure a callback for multipart upload

For multipart upload, add callback parameters to the completeMultipartUpload call — not to initiateMultipartUpload or uploadPart.

The example below uses application/json for callbackBodyType.

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Core\OssUtil;

// Load access credentials from environment variables.
// Set OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET before running this code.
$provider = new EnvironmentVariableCredentialsProvider();

// Replace with the endpoint of the region where your bucket is located.
$endpoint = "yourEndpoint";

// Replace with your bucket name, object path, and local file path.
$bucket     = "examplebucket";
$object     = "exampledir/exampleobject.txt";
$uploadFile = "D:\\localpath\\examplefile.txt";

$config = array(
    "provider"         => $provider,
    "endpoint"         => $endpoint,
    "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
    "region"           => "cn-hangzhou"
);
$ossClient = new OssClient($config);

/**
 * Step 1: Initiate a multipart upload and get the upload ID.
 * Use the upload ID to upload parts, and to cancel or query the upload task.
 */
$uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
print(__FUNCTION__ . ": initiateMultipartUpload OK\n");

/**
 * Step 2: Upload parts.
 */
$partSize      = 10 * 1024 * 1024; // 10 MB per part
$uploadFileSize = sprintf('%u', filesize($uploadFile));
$pieces        = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition     = 0;
$isCheckMd5         = true;

foreach ($pieces as $i => $piece) {
    $fromPos  = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
    $toPos    = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
    $upOptions = array(
        $ossClient::OSS_FILE_UPLOAD => $uploadFile,
        $ossClient::OSS_PART_NUM    => ($i + 1),
        $ossClient::OSS_SEEK_TO     => $fromPos,
        $ossClient::OSS_LENGTH      => $toPos - $fromPos + 1,
        $ossClient::OSS_CHECK_MD5   => $isCheckMd5,
    );

    // Compute and attach the Content-MD5 header for integrity verification.
    if ($isCheckMd5) {
        $contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
        $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
    }

    try {
        $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
    } catch (OssException $e) {
        printf(__FUNCTION__ . ": uploadPart - part#%d FAILED\n", $i);
        printf($e->getMessage() . "\n");
        return;
    }
    printf(__FUNCTION__ . ": uploadPart - part#%d OK\n", $i);
}

// Build the parts list. Each entry contains the ETag and part number returned by uploadPart.
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
    $uploadParts[] = array(
        'PartNumber' => ($i + 1),
        'ETag'       => $eTag,
    );
}

/**
 * Step 3: Complete the multipart upload and trigger the callback.
 * OSS verifies all parts, assembles the object, then sends the callback.
 */
$callback =
    '{
        "callbackUrl":"yourCallbackServerUrl",
        "callbackHost":"yourCallbackServerHost",
        "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}",
        "callbackBodyType":"application/json"
    }';

// Custom variables. Keys must start with x:.
$var =
    '{
        "x:var1":"value1",
        "x:var2":"value2"
    }';

$options = array(
    OssClient::OSS_CALLBACK     => $callback,
    OssClient::OSS_CALLBACK_VAR => $var,
);

// Pass all uploaded parts. OSS verifies each part, then assembles the final object.
$ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts, $options);
printf(__FUNCTION__ . ": completeMultipartUpload OK\n");

Replace the following placeholders before running the code:

PlaceholderDescriptionExample
yourEndpointEndpoint of the region where your bucket is locatedhttps://oss-cn-hangzhou.aliyuncs.com
examplebucketBucket namemy-bucket
exampledir/exampleobject.txtFull object path, excluding the bucket nameuploads/video.mp4
D:\\localpath\\examplefile.txtFull path of the local file to uploadD:\\videos\\sample.mp4
yourCallbackServerUrlPublicly accessible URL of your callback serverhttps://example.com/callback
yourCallbackServerHost(Optional) Host header value for the callback requestexample.com

What your callback server receives:

For multipart upload with application/json, your server receives an HTTP POST request with a body similar to:

{"mimeType":"video/mp4","size":104857600,"x:var1":"value1","x:var2":"value2"}

What's next