AWS SDK for PHP バージョン 3 での Amazon S3 マルチパートアップロードの使用
1 回の PutObject 操作では、合計サイズが 5 GB 以内のオブジェクトをアップロードできます。ただし、マルチパートアップロード手法 (たとえば、CreateMultipartUpload、UploadPart、CompleteMultipartUpload、AbortMultipartUpload) を使用すると、合計サイズが 5 MB~5 TB のオブジェクトをアップロードできます。
以下の例では、次の方法を示しています。
-
ObjectUploader を使用して、Amazon S3 にオブジェクトをアップロードする。
-
MultipartUploader を使用して、Amazon S3 オブジェクトのマルチパートアップロードを作成する。
-
ObjectCopier を使用して、Amazon S3 のある場所から別の場所にオブジェクトをコピーする。
AWS SDK for PHP 用のすべてのサンプルコードは GitHub
認証情報
サンプルコードを実行する前に、AWS の認証情報を設定します (AWS SDK for PHP バージョン 3 を使用した AWS での認証 を参照)。AWS SDK for PHP からのインポート (AWS SDK for PHP バージョン 3 のインストール を参照)。
オブジェクトアップローダー
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);
設定
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 リファレンスを参照してください。 before_initiate-
(
callable)CreateMultipartUploadオペレーションの前に呼び出すコールバック。このコールバックは、function (Aws\Command $command) {...}のような関数の署名を持っている必要があります。ファイルサイズがmup_threshold値を超えた場合、SDK はこのコールバックを呼び出します。CommandInterfaceオブジェクトに追加できるパラメータについては、CreateMultipartUpload API リファレンスを参照してください。 before_upload-
(
callable) すべてのUploadPartまたはPutObjectオペレーションの前に呼び出すコールバック。このコールバックは、function (Aws\Command $command) {...}のような関数の署名を持っている必要があります。ファイルサイズがmup_threshold値以下の場合、SDK はこのコールバックを呼び出します。PutObjectリクエストに適用できるパラメータについては、PutObject API リファレンスを参照してください。UploadPartリクエストに適用されるパラメータについては、UploadPart API リファレンスを参照してください。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
マルチパートアップロードは、大容量オブジェクトのアップロードを効率よく行えるように設計されています。マルチパートアップロードでは、オブジェクトを分割して、別々に任意の順序で並行してアップロードできます。
Amazon S3 のユーザーには、100 MB を超えるオブジェクトに対してマルチパートアップロードを使用することをお勧めします。
MultipartUploader オブジェクト
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"; }
このアップローダーでは、指定されたソースと設定に基づいてパートデータのジェネレーターが作成され、すべてのパートのアップロードが試行されます。一部のパートアップロードが失敗すると、アップローダーによってソースデータ全体が読み取られるまで、失敗したパートのアップロードが続行されます。その後、アップローダーは失敗したパートのアップロードを再試行するか、アップロードに失敗したパートに関する情報を含む例外をスローします。
マルチパートアップロードのカスタマイズ
マルチパートアップローダーによって実行される 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'; }, ]);
パートのアップロード間の手動のガベージコレクション
大きなアップロードでメモリ制限に達している場合、メモリ制限に達したときに PHP ガベージコレクター
$uploader = new MultipartUploader($client, $source, [ 'bucket' => 'your-bucket', 'key' => 'your-key', 'before_upload' => function(\Aws\Command $command) { gc_collect_cycles(); } ]);
エラーからの復旧
マルチパートアップロードのプロセスでエラーが発生すると 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 にソースとして渡されるストリームは、アップロード前に自動的には巻き戻しされません。そのため、前述の例のようなループでファイルパスではなくストリームを使用している場合は、$source ブロック内で catch 変数をリセットします。
インポート。
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);
マルチパートアップロードの中止
マルチパートアップロードは、UploadId オブジェクトに含まれた UploadState を取得し、abortMultipartUpload に渡すことで中止できます。
try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }
非同期マルチパートアップロード
upload() で MultipartUploader を呼び出すとリクエストがブロックされます。非同期コンテキストを使用している場合は、マルチパートアップロードの promise を取得できます。
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();
設定
MultipartUploader オブジェクトのコンストラクタでは次の引数を指定できます。
-
$client -
転送の実行に使用する
Aws\ClientInterfaceオブジェクト。これはAws\S3\S3Clientのインスタンスである必要があります。 -
$source -
アップロードするソースデータ。これは、パスや URL (例:
/path/to/file.jpg)、リソースハンドル (例:fopen('/path/to/file.jpg', 'r))、PSR-7 ストリームのインスタンスのいずれかです。 -
$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>]])
-
マルチパートコピー
AWS SDK for PHP には、5 GB 以上かつ 5 TB 以内のサイズのオブジェクトを Amazon S3 内でコピーするように設計されている MultipartCopy オブジェクトも含まれていて、MultipartUploader と同様の方法で使用できます。
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"; }