すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:マルチパートアップロード (PHP SDK V2)

最終更新日:Nov 09, 2025

OSS のマルチパートアップロード機能を使用すると、ラージオブジェクトを複数のパートに分割し、これらのパートを個別にアップロードできます。すべてのパートがアップロードされた後、CompleteMultipartUpload 操作を呼び出して、これらのパートを完全なオブジェクトに結合できます。

注意事項

  • このトピックのサンプルコードでは、中国 (杭州) リージョンを例として使用します。リージョン ID は cn-hangzhou です。デフォルトでは、パブリックエンドポイントが使用されます。同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。OSS がサポートするリージョンとエンドポイントの詳細については、「OSS のリージョンとエンドポイント」をご参照ください。

  • マルチパートアップロードを実行するには、oss:PutObject 権限が必要です。詳細については、「RAM ユーザーへのカスタムアクセスポリシーの付与」をご参照ください。

  • このトピックでは、環境変数からアクセス資格情報を読み取る方法の例を示します。アクセス資格情報を設定する方法のその他の例については、「PHP のアクセス資格情報の設定」をご参照ください。

マルチパートアップロードフロー

マルチパートアップロードは、次の 3 つのステップで構成されます。

  1. マルチパートアップロードイベントを初期化します。

    InitiateMultipartUpload メソッドを呼び出して、OSS からグローバルに一意のアップロード ID を取得します。

  2. パートをアップロードします。

    UploadPart メソッドを呼び出して、各パートのデータをアップロードします。

    説明
    • 同じパート番号を使用して新しいデータをアップロードすると、OSS 内のパートの既存データは上書きされます。

    • OSS は、受信したパートデータの MD5 ハッシュを ETag ヘッダーに含め、そのヘッダーを返します。

    • OSS は、アップロードされたデータの MD5 ハッシュを計算し、SDK によって計算された MD5 ハッシュと比較します。2 つの MD5 ハッシュが異なる場合、InvalidDigest エラーコードが返されます。

  3. マルチパートアップロードを完了します。

    すべてのパートがアップロードされた後、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 // マルチパートアップロードが完了した後の詳細な結果。
);

シナリオ

マルチパートアップロードを実行し、アップロードコールバックを設定する

ファイルをパート単位でアップロードした後にアプリケーションサーバーに通知したい場合は、次のサンプルコードをご参照ください。

<?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++; // パート番号をインクリメントして次のパートを処理します。
}


// x-oss-callback および x-oss-callback-var ヘッダーを追加します。
// Webhook アドレスを定義します。
$call_back_url = "http://www.example.com/callback";

// コールバックパラメーターを構築します: Webhook アドレスとコールバックのリクエストボディを指定します。Base64 エンコーディングを使用します。
// プレースホルダー {var1} と {var2} を使用して ${x:var1} と ${x:var2} を置き換えます。
$callback_body_template = "bucket={bucket}&object={object}&my_var_1={var1}&my_var_2={var2}";
$callback_body_replaced = str_replace(
    ['{bucket}', '{object}', '{var1}', '{var2}'],
    [$bucket, $key, 'value1', 'value2'],
    $callback_body_template
);
$callback = base64_encode(json_encode([
    "callbackUrl" => $call_back_url,
    "callbackBody" => $callback_body_replaced
]));

// カスタム変数 (callback-var) を構築します。Base64 エンコーディングを使用します。
$callback_var = base64_encode(json_encode([
    "x:var1" => "value1",
    "x:var2" => "value2"
]));

// マルチパートアップロードタスクを完了します。
$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 // すべてのパートのアップロード結果を送信します。
        ),
        callback: $callback,
        callbackVar: $callback_var,
    )
);

// 完了したマルチパートアップロードの結果を出力します。
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 サンプル」をご参照ください。