

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS SDK for PHP バージョン 3 での Amazon S3 マルチパートアップロードの使用
<a name="s3-multipart-upload"></a>

1 回の `PutObject` 操作では、合計サイズが 5 GB 以内のオブジェクトをアップロードできます。ただし、マルチパートアップロード手法 (たとえば、`CreateMultipartUpload`、`UploadPart`、`CompleteMultipartUpload`、`AbortMultipartUpload`) を使用すると、合計サイズが 5 MB～5 TB のオブジェクトをアップロードできます。

以下の例では、次の方法を示しています。
+ [ObjectUploader](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.ObjectUploader.html) を使用して、Amazon S3 にオブジェクトをアップロードする。
+ [MultipartUploader](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.MultipartUploader.html) を使用して、Amazon S3 オブジェクトのマルチパートアップロードを作成する。
+ [ObjectCopier](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.ObjectCopier.html) を使用して、Amazon S3 のある場所から別の場所にオブジェクトをコピーする。

のすべてのサンプルコード AWS SDK for PHP は[GitHub で入手できます](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code)。

## 認証情報
<a name="examplecredentials"></a>

サンプルコードを実行する前に、「」の説明に従って AWS 認証情報を設定します[AWS SDK for PHP バージョン 3 AWS を使用した での認証](credentials.md)。次に AWS SDK for PHP、「」の説明に従って をインポートします[AWS SDK for PHP バージョン 3 のインストール](getting-started_installation.md)。

## オブジェクトアップローダー
<a name="object-uploader"></a>

`PutObject` または `MultipartUploader` がタスクに最適かどうかが不明な場合は、`ObjectUploader` を使用します。`ObjectUploader` は、ペイロードサイズに基づいて `PutObject` または `MultipartUploader` を使用して大きなファイルを Amazon S3 にアップロードします。

```
require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\ObjectUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client.
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-2',
    'version' => '2006-03-01'
]);

$bucket = 'your-bucket';
$key = 'my-file.zip';

// Use a stream instead of a file path.
$source = fopen('/path/to/large/file.zip', 'rb');

$uploader = new ObjectUploader(
    $s3Client,
    $bucket,
    $key,
    $source
);

do {
    try {
        $result = $uploader->upload();
        if ($result["@metadata"]["statusCode"] == '200') {
            print('<p>File successfully uploaded to ' . $result["ObjectURL"] . '.</p>');
        }
        print($result);
        // If the SDK chooses a multipart upload, try again if there is an exception.
        // Unlike PutObject calls, multipart upload calls are not automatically retried.
    } catch (MultipartUploadException $e) {
        rewind($source);
        $uploader = new MultipartUploader($s3Client, $source, [
            'state' => $e->getState(),
        ]);
    }
} while (!isset($result));

fclose($source);
```

### 設定
<a name="object-uploader-configuration"></a>

`ObjectUploader` オブジェクトのコンストラクタでは次の引数を指定できます。

**`$client`**  
転送の実行に使用する `Aws\ClientInterface` オブジェクト。これは `Aws\S3\S3Client` のインスタンスである必要があります。

**`$bucket`**  
(`string`、*必須*) オブジェクトのアップロード先のバケットの名前。

**`$key`**  
(`string`、*必須*) アップロードするオブジェクトで使用するキー。

**`$body`**  
(`mixed`、*必須*) アップロードするオブジェクトデータ。`StreamInterface`、PHP ストリームリソース、またはアップロードするデータ文字列のいずれでもかまいません。

**`$acl`**  
(`string`) をアップロードするオブジェクトに設定するアクセスコントロールリスト (ACL)。デフォルトでは、オブジェクトはプライベートです。

**`$options`**  
マルチパートアップロードの設定オプションの連想配列。有効な設定オプションは次のとおりです。    
**`add_content_md5`**  
(`bool`) true に設定すると、アップロードの MD5 チェックサムが自動的に計算されます。  
**`mup_threshold`**  
(`int`、*デフォルト*:`int(16777216)`) ファイルサイズのバイト数。ファイルサイズがこの制限を超えると、マルチパートアップロードが使用されます。  
**`before_complete`**  
(`callable`) `CompleteMultipartUpload` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。`CommandInterface` オブジェクトに追加できるパラメータについては、[CompleteMultipartUpload API リファレンス](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#completemultipartupload)を参照してください。  
**`before_initiate`**  
(`callable`) `CreateMultipartUpload` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。ファイルサイズが `mup_threshold` 値を超えた場合、SDK はこのコールバックを呼び出します。`CommandInterface` オブジェクトに追加できるパラメータについては、[CreateMultipartUpload API リファレンス](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload)を参照してください。  
**`before_upload`**  
(`callable`) すべての `UploadPart` または `PutObject` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。ファイルサイズが `mup_threshold` 値以下の場合、SDK はこのコールバックを呼び出します。`PutObject` リクエストに適用できるパラメータについては、[PutObject API リファレンス](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject)を参照してください。`UploadPart` リクエストに適用されるパラメータについては、[UploadPart API リファレンス](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#uploadpart)を参照してください。SDK は、 `CommandInterface` オブジェクトで表されるオペレーションに適用されないパラメータを無視します。  
**`concurrency`**  
(`int`、*デフォルト*: `int(3)`) マルチパートアップロード中に許容される同時 `UploadPart` オペレーションの最大数。  
**`part_size`**  
(`int`、*デフォルト*: `int(5242880)`) マルチパートアップロードの実行時に使用するパートサイズ (バイト単位)。値は、5 MB 以上かつ 5 GB 以内である必要があります。  
**`state`**  
(`Aws\Multipart\UploadState`) マルチパートアップロードの状態を表すオブジェクトであり、前回のアップロードを再開するために使用されます。このオプションを指定している場合、`$bucket` および `$key` 引数と `part_size` オプションは無視されます。  
**`params`**  
各サブコマンドの設定オプションを提供する連想配列。例えば、次のようになります。  

```
new ObjectUploader($bucket, $key, $body, $acl, ['params' => ['CacheControl' => <some_value>])
```

## MultipartUploader
<a name="multipartuploader"></a>

マルチパートアップロードは、大容量オブジェクトのアップロードを効率よく行えるように設計されています。マルチパートアップロードでは、オブジェクトを分割して、別々に任意の順序で並行してアップロードできます。

Amazon S3 のユーザーには、100 MB を超えるオブジェクトに対してマルチパートアップロードを使用することをお勧めします。

## MultipartUploader オブジェクト
<a name="multipartuploader-object"></a>

SDK には、マルチパートアップロードのプロセスを簡素化する特別な `MultipartUploader` オブジェクトがあります。

 **インポート** 

```
require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

// Use multipart upload
$source = '/path/to/large/file.zip';
$uploader = new MultipartUploader($s3Client, $source, [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
]);

try {
    $result = $uploader->upload();
    echo "Upload complete: {$result['ObjectURL']}\n";
} catch (MultipartUploadException $e) {
    echo $e->getMessage() . "\n";
}
```

このアップローダーでは、指定されたソースと設定に基づいてパートデータのジェネレーターが作成され、すべてのパートのアップロードが試行されます。一部のパートアップロードが失敗すると、アップローダーによってソースデータ全体が読み取られるまで、失敗したパートのアップロードが続行されます。その後、アップローダーは失敗したパートのアップロードを再試行するか、アップロードに失敗したパートに関する情報を含む例外をスローします。

## マルチパートアップロードのカスタマイズ
<a name="customizing-a-multipart-upload"></a>

マルチパートアップローダーによって実行される `CreateMultipartUpload`、`UploadPart`、`CompleteMultipartUpload` オペレーションに対して、コンストラクタに渡すコールバックを介してカスタムオプションを設定できます。

 **インポート** 

```
require 'vendor/autoload.php';

use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

// Customizing a multipart upload
$source = '/path/to/large/file.zip';
$uploader = new MultipartUploader($s3Client, $source, [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
    'before_initiate' => function (Command $command) {
        // $command is a CreateMultipartUpload operation
        $command['CacheControl'] = 'max-age=3600';
    },
    'before_upload' => function (Command $command) {
        // $command is an UploadPart operation
        $command['RequestPayer'] = 'requester';
    },
    'before_complete' => function (Command $command) {
        // $command is a CompleteMultipartUpload operation
        $command['RequestPayer'] = 'requester';
    },
]);
```

### パートのアップロード間の手動のガベージコレクション
<a name="manual-garbage-collection-between-part-uploads"></a>

大きなアップロードでメモリ制限に達している場合、メモリ制限に達したときに [PHP ガベージコレクター](https://www.php.net/manual/en/features.gc.php)で収集されていない SDK によって生成された巡回参照が原因である可能性があります。オペレーション間で収集アルゴリズムを手動で呼び出すと、制限に達する前にサイクルを収集できます。次の例では、各パートをアップロードする前にコールバックを使用して、収集アルゴリズムを呼び出します。ガベージコレクターを呼び出してもパフォーマンスに影響することはなく、最適な使用はお客様のユースケースと環境によって異なることに注意してください。

```
$uploader = new MultipartUploader($client, $source, [
   'bucket' => 'your-bucket',
   'key' => 'your-key',
   'before_upload' => function(\Aws\Command $command) {
      gc_collect_cycles();
   }
]);
```

## エラーからの復旧
<a name="recovering-from-errors"></a>

マルチパートアップロードのプロセスでエラーが発生すると `MultipartUploadException` がスローされます。この例外では、マルチパートアップロードの進行状況に関する情報が含まれている `UploadState` オブジェクトへのアクセスが提供されます。`UploadState` を使用して、完了できなかったアップロードを再開できます。

 **インポート** 

```
require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

$source = '/path/to/large/file.zip';
$uploader = new MultipartUploader($s3Client, $source, [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
]);

//Recover from errors
do {
    try {
        $result = $uploader->upload();
    } catch (MultipartUploadException $e) {
        $uploader = new MultipartUploader($s3Client, $source, [
            'state' => $e->getState(),
        ]);
    }
} while (!isset($result));

//Abort a multipart upload if failed
try {
    $result = $uploader->upload();
} catch (MultipartUploadException $e) {
    // State contains the "Bucket", "Key", and "UploadId"
    $params = $e->getState()->getId();
    $result = $s3Client->abortMultipartUpload($params);
}
```

`UploadState` によるアップロードの再開では、まだアップロードされていないパートのアップロードが試行されます。この状態オブジェクトでは、パートが連続していない場合であっても、欠落しているパートが追跡されます。アップローダーは、指定されたソースファイルで、アップロードする必要があるパートに属するバイト範囲まで読み取りまたはシークします。

 `UploadState` オブジェクトはシリアル化可能であるため、別のプロセスでアップロードを再開することもできます。また、例外を処理していない場合でも、`UploadState` を呼び出すことによって `$uploader->getState()` オブジェクトを取得できます。

**重要**  
`MultipartUploader` にソースとして渡されるストリームは、アップロード前に自動的には巻き戻しされません。そのため、前述の例のようなループでファイルパスではなくストリームを使用している場合は、`catch` ブロック内で `$source` 変数をリセットします。

 **インポート** 

```
require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

//Using stream instead of file path
$source = fopen('/path/to/large/file.zip', 'rb');
$uploader = new MultipartUploader($s3Client, $source, [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
]);

do {
    try {
        $result = $uploader->upload();
    } catch (MultipartUploadException $e) {
        rewind($source);
        $uploader = new MultipartUploader($s3Client, $source, [
            'state' => $e->getState(),
        ]);
    }
} while (!isset($result));
fclose($source);
```

### マルチパートアップロードの中止
<a name="aborting-a-multipart-upload"></a>

マルチパートアップロードは、`UploadState` オブジェクトに含まれた `UploadId` を取得し、`abortMultipartUpload` に渡すことで中止できます。

```
try {
    $result = $uploader->upload();
} catch (MultipartUploadException $e) {
    // State contains the "Bucket", "Key", and "UploadId"
    $params = $e->getState()->getId();
    $result = $s3Client->abortMultipartUpload($params);
}
```

## 非同期マルチパートアップロード
<a name="asynchronous-multipart-uploads"></a>

`upload()` で `MultipartUploader` を呼び出すとリクエストがブロックされます。非同期コンテキストを使用している場合は、マルチパートアップロードの [promise](guide_promises.md) を取得できます。

```
require 'vendor/autoload.php';

use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

$source = '/path/to/large/file.zip';
$uploader = new MultipartUploader($s3Client, $source, [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
]);

$promise = $uploader->promise();
```

### 設定
<a name="asynchronous-multipart-uploads-configuration"></a>

`MultipartUploader` オブジェクトのコンストラクタでは次の引数を指定できます。

** `$client` **  
転送の実行に使用する `Aws\ClientInterface` オブジェクト。これは `Aws\S3\S3Client` のインスタンスである必要があります。

** `$source` **  
アップロードするソースデータ。これは、パスや URL (例: `/path/to/file.jpg`)、リソースハンドル (例: `fopen('/path/to/file.jpg', 'r)`)、[PSR-7 ストリーム](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Psr.Http.Message.StreamInterface.html)のインスタンスのいずれかです。

** `$config` **  
マルチパートアップロードの設定オプションの連想配列。  
有効な設定オプションは次のとおりです。    
** `acl` **  
(`string`) をアップロードするオブジェクトに設定するアクセスコントロールリスト (ACL)。デフォルトでは、オブジェクトはプライベートです。  
** `before_complete` **  
(`callable`) `CompleteMultipartUpload` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。  
** `before_initiate` **  
(`callable`) `CreateMultipartUpload` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。  
** `before_upload` **  
(`callable`) すべての `UploadPart` オペレーションの前に呼び出すコールバック。このコールバックは、`function (Aws\Command $command) {...}` のような関数の署名を持っている必要があります。  
** `bucket` **  
(`string`、*必須*) オブジェクトのアップロード先のバケットの名前。  
** `concurrency` **  
(`int`、*デフォルト*: `int(5)`) マルチパートアップロード中に許容される同時 `UploadPart` オペレーションの最大数。  
** `key` **  
(`string`、*必須*) アップロードするオブジェクトで使用するキー。  
** `part_size` **  
(`int`、*デフォルト*: `int(5242880)`) マルチパートアップロードの実行時に使用するパートサイズ (バイト単位)。5 MB 以上かつ 5 GB 以内である必要があります。  
** `state` **  
(`Aws\Multipart\UploadState`) マルチパートアップロードの状態を表すオブジェクトであり、前回のアップロードを再開するために使用されます。このオプションを指定している場合、`bucket`、`key`、`part_size` オプションは無視されます。  
**`add_content_md5`**  
(`boolean`) true に設定すると、アップロードの MD5 チェックサムが自動的に計算されます。  
**`params`**  
各サブコマンドの設定オプションを提供する連想配列。例えば、次のようになります。  

```
new MultipartUploader($client, $source, ['params' => ['CacheControl' => <some_value>]])
```

## マルチパートコピー
<a name="multipart-copies"></a>

には、 と同様の方法で使用される`MultipartCopy`オブジェクト AWS SDK for PHP も含まれていますが`MultipartUploader`、Amazon S3 内で 5 GB ～ 5 TB のサイズのオブジェクトをコピーするように設計されています。

```
require 'vendor/autoload.php';

use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartCopy;
use Aws\S3\S3Client;
```

 **サンプルコード** 

```
// Create an S3Client
$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-west-2',
    'version' => '2006-03-01'
]);

//Copy objects within S3
$copier = new MultipartCopy($s3Client, '/bucket/key?versionId=foo', [
    'bucket' => 'your-bucket',
    'key' => 'my-file.zip',
]);

try {
    $result = $copier->copy();
    echo "Copy complete: {$result['ObjectURL']}\n";
} catch (MultipartUploadException $e) {
    echo $e->getMessage() . "\n";
}
```