Amazon S3
S3のストレージは、各ファイルのコピーをAmazon S3に保存します。ローカルのファイルやデータベースのストレージと組み合わせて使えます。S3のストレージには、S3クライアントのプラグインが必要です。
S3クライアントのインストール
Filebinderは次の2つのS3クライアントに対応しています。
- pieceofcake2/async-aws経由のAsyncAws
- pieceofcake2/aws経由のAWS SDK for PHP
どちらか1つをインストールして読み込んでください。
AsyncAws
pieceofcake2/async-awsとasync-aws/simple-s3をインストールします。
composer require pieceofcake2/async-aws async-aws/simple-s3config/bootstrap.phpでプラグインを読み込みます。
CakePlugin::load('AsyncAws');AWS SDK for PHP
pieceofcake2/awsをインストールします。
composer require pieceofcake2/awsconfig/bootstrap.phpでプラグインを読み込みます。
CakePlugin::load('Aws');クライアントを選ぶ
Filebinderは、読み込まれているプラグインのクライアントを使います。両方のプラグインを読み込んでいる場合はAsyncAwsを使います。
クライアントを自分で選ぶには、Filebinder.S3.clientに'AsyncAws'か'Aws'を設定します。
Configure::write('Filebinder.S3.client', 'AsyncAws');選んだクライアントのプラグインは、読み込んでおく必要があります。AWS SDK for PHPをインストールしただけでは使えません。使えるクライアントがないと、ファイルを保存するときにFilebinderS3StorageExceptionが発生します。例外のメッセージには、インストールして読み込むべきパッケージが書かれています。
S3にファイルを保存する
storage設定にBindableBehavior::STORAGE_S3を加え、フィールドにバケットを設定します。
public $actsAs = [
'Filebinder.Bindable' => [
'storage' => [BindableBehavior::STORAGE_DB, BindableBehavior::STORAGE_S3],
],
];
public $bindFields = [
[
'field' => 'image',
'filePath' => '/var/www/html/myapp/webroot/files/',
'bucket' => 'my-bucket',
'acl' => 'private',
],
];ビヘイビアは、次のキーで各ファイルを保存します。
<urlPrefix><model>/<model_id>/<field_name>/<file_name>ローカルのファイルがないときは、find()がS3からダウンロードします。ファイルの復元を参照してください。
S3に置くファイルのContent-Typeは、ファイルの内容から決まります。Filebinderは、file_content_typeと同じようにfileinfo拡張で判定します。ブラウザが送ったタイプやファイルの拡張子は使いません。
S3の設定
フィールドごとに、$bindFieldsでbucket、acl、urlPrefix、regionを設定できます。ファイルのフィールドを参照してください。これらを書いていないフィールドには、Filebinder.S3の設定を使います。
Configure::write('Filebinder.S3', [
'bucket' => 'my-bucket',
'acl' => 'private',
'urlPrefix' => 'files/',
]);| 設定 | 説明 |
|---|---|
Filebinder.S3.client | 'AsyncAws'または'Aws'。デフォルトは読み込んだプラグインのクライアントです。 |
Filebinder.S3.bucket | bucketのないフィールドで使うバケット。 |
Filebinder.S3.acl | aclのないフィールドで使う既定ACL。デフォルトはpublic-readです。 |
Filebinder.S3.urlPrefix | urlPrefixのないフィールドで使うキーの接頭辞。 |
Filebinder.S3.region | 非推奨。代わりにプラグインの設定でregionを指定してください。regionのないフィールドで使うリージョンで、プラグインの設定より優先されます。 |
Filebinder.S3.key、Filebinder.S3.secret | 非推奨。プラグインの設定で認証情報を指定するか、デフォルトの認証情報を使ってください。AWSのアクセスキーで、プラグインの設定より優先されます。 |
クライアントの設定
Filebinderは、クライアントのプラグインの設定を使ってS3クライアントを作ります。リージョンと認証情報は、プラグインの設定に書いてください。
pieceofcake2/async-awsはAsyncAwsの設定を読みます。AsyncAwsがなければAwsの設定を読みます。詳しくはAsyncAwsの設定を参照してください。
Configure::write('AsyncAws', [
'region' => 'ap-northeast-1',
]);pieceofcake2/awsはAwsの設定を読みます。詳しくはAWSの設定を参照してください。
Configure::write('Aws', [
'region' => 'ap-northeast-1',
]);フィールドにregionを書くと、そのフィールドのすべてのS3リクエストで、設定のリージョンの代わりにそのリージョンを使います。
認証情報
設定に認証情報がない場合、SDKはデフォルトの認証情報を使います。
- 環境変数
- 共有の認証情報ファイル
- EC2インスタンス、ECSタスク、Lambda関数のIAMロール
Filebinder.S3.keyとFilebinder.S3.secretも引き続き使え、プラグインの設定より優先されます。ただし非推奨です。認証情報はプラグインの設定に移すか、デフォルトの認証情報を使ってください。
公開と非公開のファイル
Labelヘルパーがファイルをどうリンクするかは、ファイルのACLで決まります。ACLはフィールドのaclで、なければFilebinder.S3.aclです。デフォルトはpublic-readです。
public-readやpublic-read-writeのような公開のACLでは、ヘルパーはオブジェクトのURLを出力します。このURLは誰でも開けます。privateなどそれ以外のACLでは、ヘルパーは署名付きURLを出力します。署名付きURLはFilebinder.expireの時間で期限が切れます。デフォルトは1分です。
ファイルを非公開にするには、ACLをprivateにします。
Configure::write('Filebinder.S3.acl', 'private');署名付きURLの署名はS3が確認します。ファイルのデータはアプリケーションを通りません。ファイルのURLを参照してください。
S3ストレージのAPI
s3Storage()は、フィールドのS3ストレージを返します。返り値はFilebinderS3StorageInterfaceのインスタンスで、ビヘイビアがそのフィールドに使うのと同じ設定になっています。
$storage = $this->Post->s3Storage('image');各メソッドの引数は、オブジェクトのバケットとキーです。
$this->set('imageUrl', $storage->url('my-bucket', 'files/Post/1/image/photo.jpg'));ストレージには次のメソッドがあります。
| メソッド | 説明 |
|---|---|
put(string $bucket, string $key, string $file, array $options = []): void | ローカルのファイルをアップロードします。オプションにはACLを指定できます。 |
get(string $bucket, string $key): string | オブジェクトの内容を返します。 |
saveAs(string $bucket, string $key, string $file): void | オブジェクトをローカルのファイルにダウンロードします。 |
delete(string $bucket, string $key): void | オブジェクトを削除します。 |
url(string $bucket, string $key): string | クライアントが組み立てたオブジェクトのURLを返します。このURLには署名がありません。 |
presignedUrl(string $bucket, string $key, DateTimeImmutable $expires): string | オブジェクトをダウンロードする署名付きURLを返します。URLは$expiresで期限が切れます。 |
ストレージのファクトリー
ストレージはFilebinderS3StorageFactoryが作ります。先にクラスを読み込んでください。
App::uses('FilebinderS3StorageFactory', 'Filebinder.Storage');FilebinderS3StorageFactory::create()は、設定したクライアントのストレージを作ります。regionやcredentialsなどのクライアントのオプションを渡せます。
$storage = FilebinderS3StorageFactory::create(['region' => 'ap-northeast-1']);FilebinderS3StorageFactory::client()は、そのクライアントの名前として'AsyncAws'か'Aws'を返します。
$client = FilebinderS3StorageFactory::client();