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

Object Storage Service:フラグメントアップロード(PHP SDK V2)

最終更新日:Mar 21, 2026

フラグメントアップロードでは、ラージオブジェクトを複数のパートに分割し、それぞれを独立してアップロードします。すべてのパートのアップロードが完了したら、CompleteMultipartUpload を呼び出して、それらを 1 つのオブジェクトとしてアセンブルします。

前提条件

開始する前に、以下の条件を満たしていることを確認してください。

仕組み

フラグメントアップロードは、以下の 3 つのステップで実行されます。

  1. 初期化InitiateMultipartUpload を呼び出して、OSS からグローバルに一意なアップロード ID を取得します。

  2. パートのアップロード — 各パートに対して 1 回ずつ UploadPart を呼び出し、アップロード ID とパート番号を指定します。

  3. 完了 — アップロード済みのパート一覧を引数として CompleteMultipartUpload を呼び出して、最終的なオブジェクトをアセンブルします。

パートアップロードの動作:

  • 既存のパート番号で新しいパートをアップロードすると、そのパートの以前のデータが上書きされます。

  • OSS は各受信パートの MD5 ハッシュを ETag レスポンスヘッダーで返します。

  • OSS は、自身で計算した MD5 と SDK で計算された値を比較して整合性を検証します。一致しない場合、InvalidDigest エラーが返されます。

大規模ファイルのパート単位でのアップロード

以下の例では、ローカルファイルを 5 MB のパートに分割し、各パートを順次アップロードして、アップロードを完了します。エンドポイントは cn-hangzhou(パブリックエンドポイント)に設定されています。同一リージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、代わりに内部エンドポイントをご利用ください。

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 必須コマンドライン引数の解析:--region、--bucket、--key
// オプション:--endpoint
$optsdesc = [
    "region"   => ['help' => 'バケットが配置されているリージョン。', 'required' => True],
    "endpoint" => ['help' => '他のサービスが OSS にアクセスするために使用できるドメイン名。', 'required' => False],
    "bucket"   => ['help' => 'バケットの名称', 'required' => True],
    "key"      => ['help' => 'オブジェクトの名称', '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 "エラー:以下の引数が必要です:--$key, " . $value['help'] . PHP_EOL;
        exit(1);
    }
}

$region = $options["region"];
$bucket = $options["bucket"];
$key    = $options["key"];

// 環境変数 OSS_ACCESS_KEY_ID および 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);

// ステップ 1:フラグメントアップロードを初期化し、アップロード ID を取得
$initResult = $client->initiateMultipartUpload(
    new Oss\Models\InitiateMultipartUploadRequest(
        bucket: $bucket,
        key: $key
    )
);

// ステップ 2:ファイルを分割して各パートをアップロード
$bigFileName = "/Users/yourLocalPath/yourFileName"; // ご利用のローカルファイルのパスに置き換えてください
$partSize    = 5 * 1024 * 1024;                     // パートあたり 5 MB
$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,   // オプション:パートコンテンツの検証用 MD5 ハッシュ
            trafficLimit:  null,   // オプション:トラフィック制限
            requestPayer:  null,   // オプション:リクエスト料金の支払者
            body:          new \GuzzleHttp\Psr7\LimitStream($file, $partSize, ($i - 1) * $partSize)
        )
    );

    // アップロード完了のために必要なパート番号と ETag を収集
    $parts[] = new Oss\Models\UploadPart(
        partNumber: $i,
        etag:       $partResult->etag
    );

    $i++;
}

// ステップ 3:すべてのパートを最終的なオブジェクトとしてアセンブル
$comResult = $client->completeMultipartUpload(
    new Oss\Models\CompleteMultipartUploadRequest(
        bucket:                  $bucket,
        key:                     $key,
        uploadId:                $initResult->uploadId,
        acl:                     null, // オプション:アセンブル後のオブジェクトの ACL を設定
        completeMultipartUpload: new Oss\Models\CompleteMultipartUpload(
            parts: $parts
        )
    )
);

printf(
    '状態コード:%s' . PHP_EOL .
    'リクエスト ID:%s' . PHP_EOL .
    '結果:%s' . PHP_EOL,
    $comResult->statusCode,
    $comResult->requestId,
    var_export($comResult, true)
);

コードを実行する前に、以下のプレースホルダーを置き換えてください。

プレースホルダー説明
/Users/yourLocalPath/yourFileNameアップロードするローカルファイルの絶対パス
--region 引数バケットのリージョン ID(例:cn-hangzhou
--bucket 引数対象バケットの名称
--key 引数OSS 内で割り当てるオブジェクトキー(名称)

コールバック付きアップロード

アップロード完了後にアプリケーションサーバーに通知するには、CompleteMultipartUpload にアップロードコールバックをアタッチします。初期化およびパートアップロードのステップは、前述の基本例と同一です。完了時の呼び出しのみが異なります。

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

$optsdesc = [
    "region"   => ['help' => 'バケットが配置されているリージョン。', 'required' => True],
    "endpoint" => ['help' => '他のサービスが OSS にアクセスするために使用できるドメイン名。', 'required' => False],
    "bucket"   => ['help' => 'バケットの名称', 'required' => True],
    "key"      => ['help' => 'オブジェクトの名称', '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 "エラー:以下の引数が必要です:--$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);

// 初期化
$initResult = $client->initiateMultipartUpload(
    new Oss\Models\InitiateMultipartUploadRequest(
        bucket: $bucket,
        key: $key
    )
);

// パートのアップロード(基本例と同じロジック)
$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++;
}

// コールバックペイロードの構築 — OSS はアセンブル完了後にこのペイロードをお客様のサーバーに POST します
$call_back_url = "http://www.example.com/callback"; // お客様のサーバーのエンドポイントに置き換えてください

// コールバック本文では、OSS のシステム変数({bucket}、{object})および
// callbackVar で定義したカスタム変数({x:var1}、{x:var2})を使用できます
$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
);

// callback および callbackVar は、両方とも Base64 エンコードされた 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",
]));

// 完了 — OSS はオブジェクトのアセンブル完了後にコールバックをトリガーします
$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(
    '状態コード:%s' . PHP_EOL .
    'リクエスト ID:%s' . PHP_EOL .
    '結果:%s' . PHP_EOL,
    $comResult->statusCode,
    $comResult->requestId,
    var_export($comResult, true)
);

関連ドキュメント