laravel9のアクセサ定義を活用してS3パスを動的に生成する

13958 ワード

概要

S3上に画像ファイルを保存している場合、それを参照するWEBアプリケーションの多くはセキュリティ上の理由でtemporaryUrlを発行していると思います。

laravel9のアクセサ定義を活用すると、temporaryUrlの発行がModelにアクセスしただけで便利に取得出来てしまいます。

書き方は簡単で、カラム名をキャメルケースで該当Model内のprotected functionで定義します。今回の例だと、file_nameなのでfileNameと記載します。

こうすると、Modelを呼び出すと以下のようにtemporaryUrlメソッドを経由した値を取得出来るようになります。

レスポンス
"file_name": {
	"temporary": "http://s3ドメイン/dddf7b28-f42b-4ca8-9124-60e89833ffdd.webp?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20220426%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20220426T150530Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=6d722fa96e3bcf07740ef8b46cdfdbe7a751dee16ce9e2e311334d3262d1ba74",
	"original": "/dddf7b28-f42b-4ca8-9124-60e89833ffdd.webp"
},

値を取得する場合はカラム名にさらに矢印が生えるのでちょっと違和感なくもないですが、こんな感じで記載します。

PostImage::first()->file_name->original;

サンプルコード

以下、極力シンプルにしてありますがサンプルです。参考にしてください。

2022_03_16_232443_create_post_images_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_images', function (Blueprint $table) {
            $table->id();
            $table->string('file_name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_images');
    }
};
PostImage.php
<?php

namespace App\Models;

use App\Support\PostFileName;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class PostImage extends Model
{
    use HasFactory;

    protected $fillable = [
        'file_name',
    ];

    protected function fileName(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => new PostFileName($value),
        );
    }
}

PostFileName.php
<?php

namespace App\Support;

use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;

class PostFileName
{
    public string $temporary;
    public string $original;

    public function __construct(string $fileName)
    {
        $this->temporary = Storage::disk('s3')->temporaryUrl($fileName, Carbon::now()->addMinute(5));
        $this->original = $fileName;
    }
}

参考

Laravel 9.x Eloquent:ミューテタ/キャスト

宣伝

バックエンドにlaravelを利用して開発したアレカラというWEBサービスを運営しています。

あれから何日経った?を簡単に記録して日々の暮らしに!子育てに!推し活に!もっと毎日を記録して楽しもう!アレカラはソーシャルアカウントがあれば無料ですぐ利用出来ます。

よかったら使ってみてください。お待ちしています!!