Unggah multi-bagian membagi objek besar menjadi beberapa bagian dan mengunggahnya secara independen. Setelah semua bagian diunggah, panggil CompleteMultipartUpload untuk menyusunnya menjadi satu objek tunggal.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Bucket OSS di wilayah target
Izin
oss:PutObjectpada bucket tersebut — lihat Berikan kebijakan akses kustom kepada RAM userAccess Key ID dan Access Key Secret yang disimpan sebagai variabel lingkungan — lihat Konfigurasikan kredensial akses untuk PHP
Cara kerja
Unggah multi-bagian mengikuti tiga langkah:
Initiate — Panggil
InitiateMultipartUploaduntuk mendapatkan upload ID yang unik secara global dari OSS.Upload parts — Panggil
UploadPartsekali untuk setiap bagian, dengan menyertakan upload ID dan nomor bagian.Complete — Panggil
CompleteMultipartUploaddengan daftar bagian yang telah diunggah untuk menyusun objek akhir.
Perilaku unggah bagian:
Mengunggah bagian baru dengan nomor bagian yang sudah ada akan menimpa data sebelumnya untuk bagian tersebut.
OSS mengembalikan hash MD5 dari setiap bagian yang diterima dalam header respons
ETag.OSS memvalidasi integritas dengan membandingkan hash MD5 yang dihitungnya terhadap nilai yang dihitung oleh SDK. Ketidakcocokan akan menghasilkan error
InvalidDigest.
Unggah file besar dalam beberapa bagian
Contoh berikut membagi file lokal menjadi bagian-bagian berukuran 5 MB, mengunggah setiap bagian secara berurutan, lalu menyelesaikan proses unggah. Titik akhir diatur ke cn-hangzhou (titik akhir publik). Jika Anda mengakses OSS dari layanan Alibaba Cloud lain di wilayah yang sama, gunakan titik akhir internal sebagai gantinya.
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// Parse required command-line arguments: --region, --bucket, --key
// Optional: --endpoint
$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])) {
echo "Error: the following arguments are required: --$key, " . $value['help'] . PHP_EOL;
exit(1);
}
}
$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];
// Load credentials from environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);
$cfg->setEndpoint('http://oss-cn-hangzhou.aliyuncs.com');
$client = new Oss\Client($cfg);
// Step 1: Initiate the multipart upload and obtain an upload ID
$initResult = $client->initiateMultipartUpload(
new Oss\Models\InitiateMultipartUploadRequest(
bucket: $bucket,
key: $key
)
);
// Step 2: Split the file and upload each part
$bigFileName = "/Users/yourLocalPath/yourFileName"; // Replace with the path to your local file
$partSize = 5 * 1024 * 1024; // 5 MB per part
$fileSize = filesize($bigFileName);
$partsNum = intdiv($fileSize, $partSize) + intval(1);
$parts = [];
$i = 1;
$file = new \GuzzleHttp\Psr7\LazyOpenStream($bigFileName, 'rb');
while ($i <= $partsNum) {
$partResult = $client->uploadPart(
new Oss\Models\UploadPartRequest(
bucket: $bucket,
key: $key,
partNumber: $i,
uploadId: $initResult->uploadId,
contentLength: null, // Optional: length of the part body
contentMd5: null, // Optional: The MD5 hash of the part content for validation.
trafficLimit: null, // Optional: The traffic limit.
requestPayer: null, // Optional: The requester pays for the request.
body: new \GuzzleHttp\Psr7\LimitStream($file, $partSize, ($i - 1) * $partSize)
)
);
// Collect the part number and ETag — both are required to complete the upload
$parts[] = new Oss\Models\UploadPart(
partNumber: $i,
etag: $partResult->etag
);
$i++;
}
// Step 3: Assemble all parts into the final object
$comResult = $client->completeMultipartUpload(
new Oss\Models\CompleteMultipartUploadRequest(
bucket: $bucket,
key: $key,
uploadId: $initResult->uploadId,
acl: null, // Optional: set the ACL of the assembled object
completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
parts: $parts
)
)
);
printf(
'status code: %s' . PHP_EOL .
'request ID: %s' . PHP_EOL .
'result: %s' . PHP_EOL,
$comResult->statusCode,
$comResult->requestId,
var_export($comResult, true)
);Ganti placeholder berikut sebelum menjalankan kode:
| Placeholder | Deskripsi |
|---|---|
/Users/yourLocalPath/yourFileName | Jalur absolut ke file lokal yang ingin Anda unggah |
--region argument | ID wilayah bucket Anda, contohnya cn-hangzhou |
--bucket argument | Nama bucket tujuan Anda |
--key argument | Kunci objek (nama) yang akan digunakan di OSS |
Unggah dengan callback
Untuk memberi notifikasi ke server aplikasi setelah unggah selesai, tambahkan upload callback ke CompleteMultipartUpload. Langkah inisiasi dan unggah bagian identik dengan contoh dasar di atas — hanya pemanggilan penyelesaian yang berubah.
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
$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])) {
echo "Error: the following arguments are required: --$key, " . $value['help'] . PHP_EOL;
exit(1);
}
}
$region = $options["region"];
$bucket = $options["bucket"];
$key = $options["key"];
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);
$cfg->setEndpoint('http://oss-cn-hangzhou.aliyuncs.com');
$client = new Oss\Client($cfg);
// Initiate
$initResult = $client->initiateMultipartUpload(
new Oss\Models\InitiateMultipartUploadRequest(
bucket: $bucket,
key: $key
)
);
// Upload parts (same logic as the basic example)
$bigFileName = "/Users/yourLocalPath/yourFileName";
$partSize = 5 * 1024 * 1024;
$fileSize = filesize($bigFileName);
$partsNum = intdiv($fileSize, $partSize) + intval(1);
$parts = [];
$i = 1;
$file = new \GuzzleHttp\Psr7\LazyOpenStream($bigFileName, 'rb');
while ($i <= $partsNum) {
$partResult = $client->uploadPart(
new Oss\Models\UploadPartRequest(
bucket: $bucket,
key: $key,
partNumber: $i,
uploadId: $initResult->uploadId,
contentLength: null,
contentMd5: null,
trafficLimit: null,
requestPayer: null,
body: new \GuzzleHttp\Psr7\LimitStream($file, $partSize, ($i - 1) * $partSize)
)
);
$parts[] = new Oss\Models\UploadPart(
partNumber: $i,
etag: $partResult->etag
);
$i++;
}
// Build the callback payload — OSS will POST this to your server after assembly
$call_back_url = "http://www.example.com/callback"; // Replace with your server's endpoint
// The callback body uses OSS system variables ({bucket}, {object}) and
// custom variables ({x:var1}, {x:var2}) that you define in callbackVar.
$callback_body_template = "bucket={bucket}&object={object}&my_var_1={var1}&my_var_2={var2}";
$callback_body = str_replace(
['{bucket}', '{object}', '{var1}', '{var2}'],
[$bucket, $key, 'value1', 'value2'],
$callback_body_template
);
// Both callback and callbackVar must be Base64-encoded JSON
$callback = base64_encode(json_encode([
"callbackUrl" => $call_back_url,
"callbackBody" => $callback_body,
]));
$callback_var = base64_encode(json_encode([
"x:var1" => "value1",
"x:var2" => "value2",
]));
// Complete — OSS triggers the callback after assembling the object
$comResult = $client->completeMultipartUpload(
new Oss\Models\CompleteMultipartUploadRequest(
bucket: $bucket,
key: $key,
uploadId: $initResult->uploadId,
acl: null,
completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
parts: $parts
),
callback: $callback,
callbackVar: $callback_var,
)
);
printf(
'status code: %s' . PHP_EOL .
'request ID: %s' . PHP_EOL .
'result: %s' . PHP_EOL,
$comResult->statusCode,
$comResult->requestId,
var_export($comResult, true)
);Topik terkait
Untuk kode contoh lengkap, lihat contoh di GitHub.
Untuk semua wilayah yang didukung beserta titik akhirnya, lihat Wilayah dan titik akhir OSS.