All Products
Search
Document Center

Object Storage Service:Perform multipart upload by using OSS SDK for PHP, Perform multipart upload by using OSS SDK for PHP

Last Updated:Mar 08, 2024

Object Storage Service (OSS) provides the multipart upload feature. Multipart upload allows you to split a large object into multiple parts to upload. After these parts are uploaded, you can call the CompleteMultipartUpload operation to combine the parts into a complete object.

Procedure

To upload an object by using multipart upload, perform the following steps:

  1. Initialize a multipart upload task.

    Call $ossClient->initiateMultipartUpload to obtain a unique upload ID in OSS.

  2. Upload parts.

    Call $ossClient->uploadPart to upload parts.

    Note
    • If parts are uploaded by a multipart upload task that has a specific upload ID, part numbers are used to identify the relative positions of the parts in an object. If you upload a part that has the same part number as an existing part, the existing part is overwritten by the uploaded part.

    • OSS includes the MD5 hash of each uploaded part in the ETag header in the response.

    • OSS calculates the MD5 hash of uploaded data and compares the MD5 hash with the MD5 hash that is calculated by OSS SDK for Java. If the two hashes are different, OSS returns the InvalidDigest error code.

  3. Complete the multipart upload task.

    Call $ossClient->completeMultipartUpload to combine all parts into a complete object.

Complete sample code of a multipart upload task

The following sample code provides an example on how to implement a multipart upload task by following the multipart upload process:

<?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\CoreOssException;
use OSS\Core\OssUtil;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
$object = 'exampledir/exampleobject.txt';
// Specify the full path of the local file that you want to upload. 
$uploadFile = 'D:\\localpath\\examplefile.txt';
$initOptions = array(
    OssClient::OSS_HEADERS  => array(
        // Specify the caching behavior of the web page when the object is downloaded. 
        // 'Cache-Control' => 'no-cache',
        //Specify the name of the object when the object is downloaded. 
        // 'Content-Disposition' => 'attachment;filename=oss_download.jpg',
        // Specify the content encoding format of the object when the object is downloaded. 
        // 'Content-Encoding' => 'utf-8',
        // Specify the validity period of the request. Unit: milliseconds. 
        // 'Expires' => 150,
        // Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is initialized. In this example, this parameter is set to true, which specifies that the uploaded object that has the same name as the existing object does not overwrite the existing object. 
        //'x-oss-forbid-overwrite' => 'true',
        // Specify the server-side encryption method that you want to use to encrypt each part of the object. 
        // 'x-oss-server-side-encryption'=> 'KMS',
        // Specify the algorithm that you want to use to encrypt the object. 
        // 'x-oss-server-side-data-encryption'=>'SM4',
        // Specify the ID of the customer master key (CMK) that is managed by Key Management Service (KMS). 
        //'x-oss-server-side-encryption-key-id' => '9468da86-3509-4f8d-a61e-6eab1eac****',
        // Specify the storage class of the object. 
        // 'x-oss-storage-class' => 'Standard',
        // Specify tags for the object. You can specify multiple tags for the object at a time. 
        // 'x-oss-tagging' => 'TagA=A&TagB=B',
    ),
);

/**
 * Step 1: Initiate a multipart upload task and obtain the upload ID. 
 */
try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
    // Obtain the upload ID. The upload ID is the unique identifier of a multipart upload task. You can perform related operations such as canceling or querying the multipart upload task based on the upload ID. 
    $uploadId = $ossClient->initiateMultipartUpload($bucket, $object, $initOptions);
    print("initiateMultipartUpload OK" . "\n");
    // Cancel the multipart upload task or list uploaded parts based on the upload ID. 
    // If you want to cancel a multipart upload task based on the upload ID, obtain the upload ID after you call the InitiateMultipartUpload operation to initiate the multipart upload task.  
    // If you want to list the uploaded parts in a multipart upload task based on the upload ID, obtain the upload ID after you call the InitiateMultipartUpload operation to initiate the multipart upload task but before you call the CompleteMultipartUpload operation to complete the multipart upload task. 
    //print("UploadId: " . $uploadId . "\n");
} catch(OssException $e) {
    printf($e->getMessage() . "\n");
    return;
}

/*
 * Step 2: Upload parts. 
 */
$partSize = 10 * 1024 * 1024;
$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(
        // Upload the object. 
        $ossClient::OSS_FILE_UPLOAD => $uploadFile,
        // Specify part numbers. 
        $ossClient::OSS_PART_NUM => ($i + 1),
        // Specify the position from which the multipart upload task starts. 
        $ossClient::OSS_SEEK_TO => $fromPos,
        // Specify the object length. 
        $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
        // Specify whether to enable MD5 verification. The value true specifies that MD5 verification is enabled. 
        $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
    );
    // Enable MD5 verification. 
    if ($isCheckMd5) {
        $contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
        $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
    }
    try {
        // Upload the parts. 
        $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
        printf("initiateMultipartUpload, uploadPart - part#{$i} OK\n");
    } catch(OssException $e) {
        printf("initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
        printf($e->getMessage() . "\n");
        return;
    }

}
// $uploadParts is an array that consists of the ETag and part number of each part. 
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
    $uploadParts[] = array(
        'PartNumber' => ($i + 1),
        'ETag' => $eTag,
    );
}
/**
 * Step 3: Complete the multipart upload task. 
 */
$comOptions['headers'] = array(
    // Specify whether the object that is uploaded by using multipart upload overwrites the existing object that has the same name when the multipart upload task is complete. In this example, this parameter is set to true, which specifies that the uploaded object that has the same name as the existing object does not overwrite the existing object. 
    // 'x-oss-forbid-overwrite' => 'true',
    // If you set the x-oss-complete-all parameter to yes, OSS lists all parts that are uploaded by using the current upload ID, sorts the parts by part number, and then performs the CompleteMultipartUpload operation. 
    // 'x-oss-complete-all'=> 'yes'
);

try {
    // All valid values of the $uploadParts parameter are required for the CompleteMultipartUpload operation. After OSS receives the values of the $uploadParts parameter, OSS verifies all parts one by one. After all parts are verified, OSS combines the parts into a complete object. 
    $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts,$comOptions);
    printf( "Complete Multipart Upload OK\n");
}  catch(OssException $e) {
    printf("Complete Multipart Upload FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
           

Upload a local file by using multipart upload

The following sample code provides an example on how to upload a local file to OSS by performing multipart upload:

<?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\CoreOssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
$object = 'exampledir/exampleobject.txt';
// Specify the full path of the local file that you want to upload. 
$file = 'D:\\localpath\\examplefile.txt';

$options = array(
    OssClient::OSS_CHECK_MD5 => true,
    OssClient::OSS_PART_SIZE => 1,
);
try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $ossClient->multiuploadFile($bucket, $object, $file, $options);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ":  OK" . "\n");            

Upload a local directory by performing multipart upload

The following sample code provides an example on how to upload a local directory, including all files in the directory, to OSS by performing multipart upload:

<?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\CoreOssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';
// Specify the full path of the local directory that you want to upload. 
$localDirectory = "D:\\localpath";
// Specify the prefix of the directory. 
$prefix = "samples/codes/";
try {
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $ossClient->uploadDir($bucket, $prefix, $localDirectory);
}  catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ":  OK" . "\n");            

Cancel a multipart upload task

You can use the $ossClient->abortMultipartUpload method to cancel a multipart upload task. If a multipart upload task is canceled, the upload ID cannot be used to upload parts. In addition, the uploaded parts are deleted.

<?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\CoreOssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
$object = 'exampledir/exampleobject.txt';
// Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. You can obtain the upload ID from the response to the InitiateMultipartUpload operation. 
$upload_id = '0004B999EF518A1FE585B0C9360D****';

try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $ossClient->abortMultipartUpload($bucket, $object, $upload_id);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": OK" . "\n");            

List uploaded parts

You can use the listParts method to list all parts that are uploaded by using the specified upload ID.

<?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\CoreOssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
$object = 'exampledir/exampleobject.txt';
// Specify the upload ID. Example: 0004B999EF518A1FE585B0C9360D****. You can obtain the upload ID from the response to the InitiateMultipartUpload operation. You must obtain the upload ID before you call the CompleteMultipartUpload operation to complete the multipart upload task. 
$upload_id = '0004B999EF518A1FE585B0C9360D****';

try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $listPartsInfo = $ossClient->listParts($bucket, $object, $uploadId);
    foreach ($listPartsInfo->getListPart() as $partInfo) {
        print($partInfo->getPartNumber() . "\t" . $partInfo->getSize() . "\t" . $partInfo->getETag() . "\t" . $partInfo->getLastModified() . "\n");
    }
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": OK" . "\n");            

List multipart upload tasks

You can use the listMultipartUploads method to list all ongoing multipart upload tasks. Ongoing multipart upload tasks are tasks that have been initiated but are not completed or canceled.

<?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\CoreOssException;

// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.  
$provider = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// Specify the name of the bucket. Example: examplebucket. 
$bucket= 'examplebucket';

$options = array(
    'delimiter' => '/',
    'max-uploads' => 100,
    'key-marker' => '',
    'prefix' => '',
    'upload-id-marker' => ''
);
try {
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);

    $listMultipartUploadInfo = $ossClient->listMultipartUploads($bucket, $options);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": listMultipartUploads FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
printf(__FUNCTION__ . ": listMultipartUploads OK\n");
$listUploadInfo = $listMultipartUploadInfo->getUploads();
var_dump($listUploadInfo);            

The following table describes the parameters included in $options in the preceding sample code.

Parameter

Description

delimiter

The delimiter character used to group object names. Objects whose names contain the same string from the prefix and the next occurrence of the delimiter are grouped as a single result element in the commonPrefixes parameter.

key-marker

The position from which the next list starts. This parameter is used together with the upload-id-marker parameter to list all multipart upload tasks for objects whose names are alphabetically greater than the value of key-marker. This parameter is used together with the upload-id-marker parameter to specify the position from which the next list starts.

max-uploads

The maximum number of multipart upload tasks that you want to return for the current list. Maximum value: 1000. Default value: 1000.

prefix

The prefix that must be included in the names of the returned objects.

Note

If you use a prefix for a query, the returned object names contain the prefix.

upload-id-marker

The upload ID of the multipart upload task from which the list starts. This parameter is used together with the key-marker parameter. If the key-marker parameter is not specified, the upload-id-marker parameter is invalid. If the key-marker parameter is specified, the query result includes:

  • All objects whose names are alphabetically greater than the value of key-marker

  • All multipart upload tasks with the same object name as the value of key-marker and upload IDs that are greater than the value of upload-id-marker

References

  • For the complete sample code that is used to perform multipart upload, visit GitHub.

  • A multipart upload involves three API operations. For more information about the operations, see the following topics:

  • For more information about the API operation that you can call to cancel a multipart upload task, see AbortMultipartUpload.

  • For more information about the API operation that you can call to list uploaded parts, see ListParts.

  • For more information about the API operation that you can call to list all ongoing multipart upload tasks, see ListMultipartUploads. Ongoing multipart upload tasks are tasks that have been initiated but are not completed or canceled.