OSS のマルチパートアップロード機能を使用すると、ラージオブジェクトを複数のパートに分割し、これらのパートを個別にアップロードできます。すべてのパートがアップロードされた後、CompleteMultipartUpload 操作を呼び出して、これらのパートを完全なオブジェクトに結合できます。
注意事項
このトピックのサンプルコードでは、中国 (杭州) リージョンを例として使用します。リージョン ID は
cn-hangzhouです。デフォルトでは、パブリックエンドポイントが使用されます。同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。OSS がサポートするリージョンとエンドポイントの詳細については、「OSS のリージョンとエンドポイント」をご参照ください。マルチパートアップロードを実行するには、
oss:PutObject権限が必要です。詳細については、「RAM ユーザーへのカスタムアクセスポリシーの付与」をご参照ください。このトピックでは、環境変数からアクセス資格情報を読み取る方法の例を示します。アクセス資格情報を設定する方法のその他の例については、「PHP のアクセス資格情報の設定」をご参照ください。
マルチパートアップロードフロー
マルチパートアップロードは、次の 3 つのステップで構成されます。
マルチパートアップロードイベントを初期化します。
InitiateMultipartUpload メソッドを呼び出して、OSS からグローバルに一意のアップロード ID を取得します。
パートをアップロードします。
UploadPart メソッドを呼び出して、各パートのデータをアップロードします。
説明同じパート番号を使用して新しいデータをアップロードすると、OSS 内のパートの既存データは上書きされます。
OSS は、受信したパートデータの MD5 ハッシュを ETag ヘッダーに含め、そのヘッダーを返します。
OSS は、アップロードされたデータの MD5 ハッシュを計算し、SDK によって計算された MD5 ハッシュと比較します。2 つの MD5 ハッシュが異なる場合、InvalidDigest エラーコードが返されます。
マルチパートアップロードを完了します。
すべてのパートがアップロードされた後、CompleteMultipartUpload メソッドを呼び出して、パートを完全なファイルに結合します。
サンプルコード
次のサンプルコードは、大きなローカルファイルを複数のパートに分割し、パートをバケットにアップロードしてから、パートを完全なオブジェクトに結合する方法を示しています。
<?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], // OSS へのアクセスに使用できるエンドポイント。(オプション)
"bucket" => ['help' => 'The name of the bucket', 'required' => True], // バケットの名前。(必須)
"key" => ['help' => 'The name of the object', 'required' => True], // オブジェクトの名前。(必須)
];
// 引数の説明を getopt で必要なロングオプション形式に変換します。
// 各引数の後のコロン (:) は、引数に値が必要であることを示します。
$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])) {
$help = $value['help']; // 引数のヘルプ情報を取得します。
echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
exit(1); // 必須の引数が欠落している場合は、プログラムを終了します。
}
}
// 解析された引数から値を抽出します。
$region = $options["region"]; // バケットが配置されているリージョン。
$bucket = $options["bucket"]; // バケットの名前。
$key = $options["key"]; // オブジェクトの名前。
// 環境変数から資格情報情報をロードします。
// EnvironmentVariableCredentialsProvider を使用して、環境変数から Access Key ID と Access Key Secret を読み取ります。
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// SDK のデフォルト設定を使用します。
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 資格情報プロバイダーを設定します。
$cfg->setRegion($region); // バケットが配置されているリージョンを設定します。
$cfg->setEndpoint('http://oss-cn-hangzhou.aliyuncs.com'); // エンドポイントを設定します。
// OSS クライアントインスタンスを作成します。
$client = new Oss\Client($cfg);
// マルチパートアップロードタスクを初期化します。
$initResult = $client->initiateMultipartUpload(
new Oss\Models\InitiateMultipartUploadRequest(
bucket: $bucket,
key: $key
)
);
// ラージファイルのパスとパートサイズを定義します。
$bigFileName = "/Users/yourLocalPath/yourFileName"; // ラージファイルのパスを指定します。
$partSize = 5 * 1024 * 1024; // パートサイズをバイト単位で設定します。この例では、パートサイズは 5 MB に設定されています。
$fileSize = filesize($bigFileName); // ファイルサイズを取得します。
$partsNum = intdiv($fileSize, $partSize) + intval(1); // パート数を計算します。
$parts = []; // 各パートのアップロード結果を格納するために使用されます。
$i = 1; // パート番号は 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, // 開始されたアップロードタスクによって返されたアップロード ID。
contentLength: null, // オプション: パートのコンテンツ長。
contentMd5: null, // オプション: 検証用のパートコンテンツの MD5 ハッシュ。
trafficLimit: null, // オプション: トラフィック制限。
requestPayer: null, // オプション: リクエスターがリクエストの料金を支払います。
body: new \GuzzleHttp\Psr7\LimitStream($file, $partSize, ($i - 1) * $partSize) // 現在のパートのデータを読み取ります。
)
);
// パートのアップロード結果を保存します。
$part = new Oss\Models\UploadPart(
partNumber: $i, // パート番号。
etag: $partResult->etag // パートがアップロードされた後に返される ETag 値。
);
array_push($parts, $part); // 現在のパートのアップロード結果をパートリストに保存します。
$i++; // パート番号をインクリメントして次のパートを処理します。
}
// マルチパートアップロードタスクを完了します。
$comResult = $client->completeMultipartUpload(
new Oss\Models\CompleteMultipartUploadRequest(
bucket: $bucket,
key: $key,
uploadId: $initResult->uploadId, // 開始されたアップロードタスクによって返されたアップロード ID。
acl: null, // オプション: オブジェクトのアクセス制御リスト (ACL) を設定します。
completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
parts: $parts // すべてのパートのアップロード結果を送信します。
)
)
);
// 完了したマルチパートアップロードの結果を出力します。
printf(
'status code:' . $comResult->statusCode . PHP_EOL . // HTTP ステータスコード。たとえば、200 はリクエストが成功したことを示します。
'request id:' . $comResult->requestId . PHP_EOL . // リクエスト ID。リクエストのデバッグや追跡に使用されます。
'complete multipart upload result:' . var_export($comResult, true) . PHP_EOL // マルチパートアップロードが完了した後の詳細な結果。
);
シナリオ
関連情報
マルチパートアップロードの完全なサンプルコードについては、「GitHub サンプル」をご参照ください。