diecoding / yii2-aws-s3
为 Yii2 使用的 Amazon S3 或 Amazon Simple Storage Service 组件
Requires
- php: >=7.4.0
- aws/aws-sdk-php: ~3.263
- yiisoft/yii2: ~2.0
Requires (Dev)
- phpunit/phpunit: ~9.5.0
README
为 Yii2 使用的 Amazon S3 或 Amazon Simple Storage Service 组件。
Yii2 AWS S3 使用 SemVer。
目录
安装
该包可在 Packagist 上找到,您可以使用 Composer 安装它。
composer require diecoding/yii2-aws-s3 "^1.0"
或将其添加到您的 composer.json 文件的 require 部分中。
"diecoding/yii2-aws-s3": "^1.0"
依赖
- PHP 7.4+
- yiisoft/yii2
- aws/aws-sdk-php
配置
-
将组件添加到
config/main.php'components' => [ // ... 's3' => [ 'class' => \diecoding\aws\s3\Service::class, 'endpoint' => 'my-endpoint', 'usePathStyleEndpoint' => true, 'credentials' => [ // Aws\Credentials\CredentialsInterface|array|callable 'key' => 'my-key', 'secret' => 'my-secret', ], 'region' => 'my-region', 'defaultBucket' => 'my-bucket', 'defaultAcl' => 'public-read', ], // ... ],
使用
基本使用
/** @var \diecoding\aws\s3\Service $s3 */ $s3 = Yii::$app->get('s3'); // or $s3 = Yii::$app->s3; // Usage of the command factory and additional params // ================================================== /** @var \Aws\ResultInterface $result */ $result = $s3->commands()->get('filename.ext')->saveAs('/path/to/local/file.ext')->execute(); $result = $s3->commands()->put('filename.ext', 'body')->withContentType('text/plain')->execute(); $result = $s3->commands()->delete('filename.ext')->execute(); $result = $s3->commands()->upload('filename.ext', '/path/to/local/file.ext')->withAcl('private')->execute(); $result = $s3->commands()->restore('filename.ext', $days = 7)->execute(); $result = $s3->commands()->list('path/')->execute(); /** @var bool $exist */ $exist = $s3->commands()->exist('filename.ext')->execute(); /** @var string $url */ $url = $s3->commands()->getUrl('filename.ext')->execute(); /** @var string $signedUrl */ $signedUrl = $s3->commands()->getPresignedUrl('filename.ext', '+2 days')->execute(); // Short syntax // ============ /** @var \Aws\ResultInterface $result */ $result = $s3->get('filename.ext'); $result = $s3->put('filename.ext', 'body'); $result = $s3->delete('filename.ext'); $result = $s3->upload('filename.ext', '/path/to/local/file.ext'); $result = $s3->restore('filename.ext', $days = 7); $result = $s3->list('path/'); /** @var bool $exist */ $exist = $s3->exist('filename.ext'); /** @var string $url */ $url = $s3->getUrl('filename.ext'); /** @var string $signedUrl */ $signedUrl = $s3->getPresignedUrl('filename.ext', '+2 days'); // Asynchronous execution // ====================== /** @var \GuzzleHttp\Promise\PromiseInterface $promise */ $promise = $s3->commands()->get('filename.ext')->async()->execute(); $promise = $s3->commands()->put('filename.ext', 'body')->async()->execute(); $promise = $s3->commands()->delete('filename.ext')->async()->execute(); $promise = $s3->commands()->upload('filename.ext', 'source')->async()->execute(); $promise = $s3->commands()->list('path/')->async()->execute();
高级使用
/** @var \diecoding\aws\s3\Service $s3 */ $s3 = Yii::$app->get('s3'); // or $s3 = Yii::$app->s3; /** @var \diecoding\aws\s3\commands\GetCommand $command */ $command = $s3->create(GetCommand::class); $command->inBucket('my-another-bucket')->byFilename('filename.ext')->saveAs('/path/to/local/file.ext'); /** @var \Aws\ResultInterface $result */ $result = $s3->execute($command); // or async /** @var \GuzzleHttp\Promise\PromiseInterface $promise */ $promise = $s3->execute($command->async());
自定义命令
命令有两种类型:由 PlainCommandHandler 处理的普通命令和具有自己处理器的命令。普通命令封装了本机 AWS S3 命令。
普通命令必须实现 PlainCommand 接口,其余必须实现 Command 接口。如果命令没有实现 PlainCommand 接口,则必须有自己的处理器。
每个处理器都必须扩展 Handler 类或实现 Handler 接口。处理器在构造函数中获取 S3Client 实例。
HasBucket 和 HasAcl 接口的实现允许命令构建器默认设置桶和 acl 的值。
要使普通命令异步,您必须实现 Asynchronous 接口。您还可以使用 Async 特性来实现此接口。
考虑以下命令
<?php namespace app\components\s3\commands; use diecoding\aws\s3\base\commands\traits\Options; use diecoding\aws\s3\interfaces\commands\Command; use diecoding\aws\s3\interfaces\commands\HasBucket; class MyCommand implements Command, HasBucket { use Options; protected $bucket; protected $something; public function getBucket() { return $this->bucket; } public function inBucket(string $bucket) { $this->bucket = $bucket; return $this; } public function getSomething() { return $this->something; } public function withSomething(string $something) { $this->something = $something; return $this; } }
此命令的处理程序看起来像这样
<?php namespace app\components\s3\handlers; use app\components\s3\commands\MyCommand; use diecoding\aws\s3\base\handlers\Handler; class MyCommandHandler extends Handler { public function handle(MyCommand $command) { return $this->s3Client->someAction( $command->getBucket(), $command->getSomething(), $command->getOptions() ); } }
使用此命令
/** @var \diecoding\aws\s3\Service $s3 */ $s3 = Yii::$app->get('s3'); // or $s3 = Yii::$app->s3; /** @var \app\components\s3\commands\MyCommand $command */ $command = $s3->create(MyCommand::class); $command->withSomething('some value')->withOption('OptionName', 'value'); /** @var \Aws\ResultInterface $result */ $result = $s3->execute($command);
自定义普通命令看起来像这样
<?php namespace app\components\s3\commands; use diecoding\aws\s3\interfaces\commands\HasBucket; use diecoding\aws\s3\interfaces\commands\PlainCommand; class MyPlainCommand implements PlainCommand, HasBucket { protected $args = []; public function getBucket() { return $this->args['Bucket'] ?? ''; } public function inBucket(string $bucket) { $this->args['Bucket'] = $bucket; return $this; } public function getSomething() { return $this->args['something'] ?? ''; } public function withSomething($something) { $this->args['something'] = $something; return $this; } public function getName(): string { return 'AwsS3CommandName'; } public function toArgs(): array { return $this->args; } }
任何命令都可以扩展 ExecutableCommand 类或实现 Executable 接口,这将允许立即执行此命令:$command->withSomething('some value')->execute();。
使用特性
模型特性
将特性附加到具有某些媒体属性的 Model/ActiveRecord 上,这些属性将保存到 S3
/** * @property string|null $file */ class Model extends \yii\db\ActiveRecord { use \diecoding\aws\s3\traits\ModelTrait; // ... public function rules() { return [ ['image', 'string'], // Stores the filename ]; } /** * @inheritdoc */ protected function attributePaths() { return [ 'image' => 'images/' ]; } // ... }
重写 attributePaths() 方法以更改文件在 AWS S3 上保存的基路径。
- 您可以将不同的路径映射到
Model/ActiveRecord的每个文件属性。
使用特性方法
$image = \yii\web\UploadedFile::getInstance($model, 'image'); // Save image_thumb.* to S3 on //my_bucket/images/ path // The extension of the file will be determined by the submitted file type // This allows multiple file types upload (png,jpg,gif,...) // $model->image will hold "image_thumb.png" after this call finish with success $model->saveUploadedFile($image, 'image', 'image_thumb'); // Save image_thumb.png to S3 on //my_bucket/images/ path // The extension of the file will be determined by the submitted file type // This force the extension to *.png $model->saveUploadedFile($image, 'image', 'image_thumb.png', false); // Get the URL to the image on S3 $model->getFileUrl('image'); // Get the presigned URL to the image on S3 // The default duration is "+5 Minutes" $model->getFilePresignedUrl('image'); // Remove the file with named saved on the image attribute // Continuing the example, here "//my_bucket/images/my_image.png" will be deleted from S3 $model->removeFile('image');
重写特性方法
getS3Component
S3MediaTrait 依赖于此组件进行配置。默认配置是在索引 's3' 上使用此组件,但您可以使用其他值。在这种情况下,重写 getS3Component() 方法
public function getS3Component() { return Yii::$app->get('my_s3_component'); }
attributePaths
主要需要重写的方法是 attributePaths(),它为您的模型中的每个属性定义了 S3 中的路径。这允许您在每个不同的 S3 文件夹中保存每个属性。
以下是一个示例
protected function attributePaths() { return [ 'logo' => 'logos/', 'badge' => 'images/badges/' ]; } // or use another attribute, example: id // ! Note: id must contain a value first if you don't want it to be empty protected function attributePaths() { return [ 'logo' => 'thumbnail/' . $this->id . '/logos/', 'badge' => 'thumbnail/' . $this->id . '/images/badges/' ]; }
getPresignedUrlDuration
默认的预签名 URL 持续时间为 "+5 分钟",重写此方法并使用您自己的过期时间。
protected function getPresignedUrlDuration($attribute) { return '+2 Hours'; } // or if you want to set the attribute differently protected function getPresignedUrlDuration($attribute) { switch ($attribute) { case 'badge': return '+2 Hours'; break; default: return '+1 Days'; break; } }
值应该是有效的 PHP datetime 操作。有关详细信息,请参阅 PHP 文档
isSuccessResponseStatus
isSuccessResponseStatus() 方法验证 AWS 响应的状态代码为 2**。如果需要,您可以重写此验证
protected function isSuccessResponseStatus($response) { // Response is always valid return true; }
阅读更多文档:https://sugengsulistiyawan.my.id/docs/opensource/yii2/aws-s3/