AUTOVICE

TECH BLOG

【Laravel】ローカルディスクやAmazon S3にアップロードした画像をビューで表示する方法

2021-02-15

はじめに

本記事では、ローカルディスクやAmazon S3にアップロードした画像をビューで表示する方法について説明しています。

なお、本記事では画像のアップロードする方法については説明していません。本記事は既に実装済みの画像アップロード処理に追加していく形で説明しているので、まだ実装していない方は以下の記事を参照して実装してください。

アップロードした画像の表示

テーブルの作成

以下のコマンドを実行して、アップロードした画像のURI(参照先)を保存しておくためのテーブルを作成します。

$ php artisan make:migration create_table_posts --table=posts

作成したマイグレーションファイル(database/migrations/Y_m_d_XXX_create_table_posts.php)を以下のように変更します。

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            # 以下の行を追加
            $table->string('image');
            $table->timestamps();
        });
    }

以下のコマンドを実行して、マイグレーションを実行します。

$ php artisan migrate

以下のコマンドを実行して、モデルを作成します。

$ php artisan make:model Post

コントローラーの実装

コントローラーを以下のように変更します。

    public function store(Request $request)
    {
        $post = new Post();

        # 画像ファイルのアップロード
        $image = $request->file('image');
        if ( app()->isLocal() || app()->runningUnitTests() ) {
            # 開発環境
            $path = $image->store('public/images');
            $post->image = Storage::url($path);
        }
        else {
            # 本番環境
            $path = Storage::disk('s3')->put('/', $image, 'public');
            $post->image = Storage::disk('s3')->url($path);
        }

        Auth::user()->posts()->save($post);

        return redirect()->route('posts.index');
    }

以下の行で作成したテーブルにアップロード画像のURIを保存しています。

# 開発環境
$post->image = Storage::url($path);

# 本番環境
$post->image = Storage::disk('s3')->url($path);

storeメソッドはstorage/app/public/〜というパスを返します。このパスはブラウザからは参照できません。ブラウザから参照するにはpublic/〜経由でアップロード画像を参照する必要があります。Storage::urlメソッドは、storage/app/public/〜public/〜に変換するメソッドになります。

シンボリックリンクの作成

以下のコマンドを実行して、storage/app/public/〜public/〜を紐付けるシンボリックリンクを作成します。このシンボリックリンクを作成することで、storage/app/public/〜に保存されたアップロード画像がpublic/〜経由で参照可能になります。

$ php artisan storage:link

ビューの実装

アップロード画像の参照可能なURIはテーブルに保存してあるので、以下のように記述するだけです。開発環境の場合はローカル(/public/storage/〜)のURIが、本番環境の場合はAmazon S3のURLが参照されます。

<img src="{{ $post->image }}" />

まとめ

保存される場所と参照する場所が違うため最初は複雑だと思うかもしれませんが、理解してしまえば難しいことはありません。

アップロードした画像がビューで表示できないという場合は、参照しているURIがstorage/app/public/〜になっている可能性があります。ブラウザからはpublic/〜しか参照できないため、URIの変換を忘れないようにしてください。