S3のcommandPoolに関して。
S3にファイルをアップロード、ダウンロードするときに、1つ1つファイルをアップロード、ダウンロードすることが一般的かと思いますが、ファイル数が多くなるとなかなか時間がかかってしまいます。
そこで一気にファイルをアップロード、ダウンロードできる手法があります。
要領としてはコマンドをあらかじめ登録しておき、一気に処理を行うというもので、SQLのバルクインサート(bulk insert)などに近いと思います。
ソース
CommandPool.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?php require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/AWSS3Util.php'; $dotenv = Dotenv\Dotenv::create(__DIR__); $dotenv->load(); $aws3Util = new AWSS3Util([ 'aws_access_key' => getenv('ACCESS_KEY'), 'aws_secret_key' => getenv('SECRET_KEY'), 'region' => getenv('REGION') ]); bulkUpload($aws3Util); bulkDownload($aws3Util); function bulkDownload($aws3Util) { $saveFileDir = __DIR__ . '/sample_image'; $fileLists = $aws3Util->getS3FileList(getenv('BUCKET_NAME'), 'sample_image'); $imageData = []; foreach ($fileLists as $file) { if (!empty($file)) { $imageData[] = 'sample_image/' . $file; } } $aws3Util->bulkSaveS3Contents(getenv('BUCKET_NAME'), $saveFileDir, $imageData); } function bulkUpload($aws3Util) { $dir = __DIR__ . '/sample_image/*'; $imageData = []; foreach (glob($dir) as $file_path) { $file_info = new SplFileInfo($file_path); $file_name = $file_info->getFilename(); $extension = $file_info->getExtension(); $image_binary = file_get_contents($file_path); $imageData[] = [ 'key' => 'sample_image/' . $file_name, 'body' => $image_binary, 'mimeType' => $extension ]; } $aws3Util->bulkPutS3ContentsBinary(getenv('BUCKET_NAME'), $imageData); } |
AWSS3Util.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
<?php use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; use Aws\CommandPool; class AWSS3Util { private $credentials = []; private $region = ''; private $version = ''; private $s3Client = null; /** * * 一括S3への保存(バイナリデータを直で) * * @param string $bucket バケット名 * @param mixed $imageData key => binaryデータ * @param string $mimeType mime_type */ public function bulkPutS3ContentsBinary($bucket, $imageData) { $commands = []; foreach ($imageData as $eachImageData) { $commands[] = $this->s3Client->getCommand('PutObject', [ 'Bucket' => $bucket, 'Key' => $eachImageData['key'], 'Body' => $eachImageData['body'], 'ContentType'=> 'image/' . $eachImageData['mimeType'], 'ACL' => 'public-read' ]); } $pool = new CommandPool($this->s3Client, $commands); $promise = $pool->promise(); // Force the pool to complete synchronously $promise->wait(); } /** * S3からファイルを保存 * * @param string $bucket S3のバケット(トップのディレクトリのようなもの) * @param string $fileDir ファイルディレクトリ * @param string $imageData アップロードデータ */ public function bulkSaveS3Contents($bucket, $fileDir, $imageData) { $commands = []; foreach ($imageData as $eachImageData) { $fileArr = explode("/", $eachImageData); $lastIndex = count($fileArr); $fileName = $fileArr[$lastIndex - 1]; if (!file_exists($fileDir)) { mkdir($fileDir, 0777, true); } $filePath = sprintf("%s/%s", $fileDir, $fileName); $commands[] = $this->s3Client->getCommand('GetObject', [ 'Bucket' => $bucket, 'Key' => $eachImageData, 'SaveAs' => $filePath ]); } $pool = new CommandPool($this->s3Client, $commands); $promise = $pool->promise(); // Force the pool to complete synchronously $promise->wait(); } } |
参考リンク
https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/guide_commands.html
[AWS SDK for PHP] S3へ一括でコマンドを実行したい場合はCommandPoolを使えという話