PHP/Laravel プログラミング

Laravelで画像のアップロードと表示してみよう

投稿日:

Laravelでは画像ファイルを扱うための機能が用意されているので、簡単に画像ファイルを操作することができます。

この記事では画像をアップロードしたり表示させたりする機能を実装することで、Laravelでの画像ファイルの扱い方を理解していきましょう。

画像をアップロードする

まずはViewで画像をアップロードするためのフォームを用意します。

<form method="POST" action="/upload" enctype="multipart/form-data">
  @csrf
  <input type="file" name="image">
  <button>アップロード</button>
</form>

フォームを作成する際に大事なのがenctype="multipart/form-data"をformタグに設定することです。この設定をしないと画像ファイルを送信することができません。

inputタグのtype="file"で画像ファイルを選択し、入力することができます。

アップロードされた画像を保存

フォームでアップロードされた画像ファイルをコントローラー内の処理で保存していきます。

画像ファイルを保存

アップロードされたファイルのインスタンスではファイルを操作するためのメソッドが用意されています。

画像ファイルを保存するためには、storeメソッドを使用します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    public function upload(Request $request)
    {
        // ディレクトリ名
        $dir = 'sample';

        // sampleディレクトリに画像を保存
        $request->file('image')->store('public/' . $dir);

        return redirect('/');
    }
}

storeメソッドの引数では保存先のディレクトリ名を指定することができます。

アップロードされた画像ファイルはプロジェクト直下のstorageディレクトリ内のapp>public>sampleディレクトリにランダムな一意のIDのファイル名で保存されます。

名前を付けて画像ファイルを保存

storage/app/public/sampleディレクトリの下に画像ファイルが保存されているのが確認できます。

storeAsメソッドを使用することでファイル名を指定して保存することもできます。

ここではアップロードされた画像ファイル名を取得して、そのファイル名のまま保存してみましょう。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    public function upload(Request $request)
    {
        // ディレクトリ名
        $dir = 'sample';

        // アップロードされたファイル名を取得
        $file_name = $request->file('image')->getClientOriginalName();

        // 取得したファイル名で保存
        $request->file('image')->storeAs('public/' . $dir, $file_name);

        return redirect('/');
    }
}

storage/app/public/sampleディレクトリの下に任意のファイル名で画像ファイルを保存されていることが確認できます。

画像パスをDBに保存

画像を表示する際に画像のパスが必要になるので、画像パスをデータとして持つようなテーブルを作成しましょう。

imagesテーブル生成のマイグレーションファイルを作成します。

$ php artisan make:migration create_images_table --create=images
<?php

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

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

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('images');
    }
}

ファイル名を保存する「name」カラムとファイルパスを保存する「path」カラムを用意しました。

マイグレーションファイルの作成が完了したら下記のコマンドでマイグレーションを実行しましょう。

$ php artisan migrate

テーブルが準備できたら、テーブルに対応するモデルクラスを作成していきましょう。

$ php artisan make:model Image
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
  protected $fillable = [
    'name',
    'path',
  ];
}

$fillableを定義しただけで、他はファイルを生成した時と変わりません。

それでは画像アップロード時に画像を保存した後に画像のデータもデータベースに保存するようにコントローラーに処理を追加しましょう。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Image;

class ImageController extends Controller
{
    public function upload(Request $request)
    {
        // ディレクトリ名
        $dir = 'sample';

        // アップロードされたファイル名を取得
        $file_name = $request->file('image')->getClientOriginalName();

        // 取得したファイル名で保存
        $request->file('image')->storeAs('public/' . $dir, $file_name);

        // ファイル情報をDBに保存
        $image = new Image();
        $image->name = $file_name;
        $image->path = 'storage/' . $dir . '/' . $file_name;
        $image->save();

        return redirect('/');
    }
}

画像パスを保存する際は、storage/ディレクトリ/ファイル名というパスで保存するようにしましょう。このようなパスで保存する理由は後ほど説明します。

これで画像のアップロード処理は実装完了です。

アップロードされた画像を表示

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

画像はアップロードされるとプロジェクト直下のstorage/app/publicディレクトリの下にファイルが配置されることを確認しました。

しかしこのままではブラウザからアクセスすることができないため表示することができません。

アップロードされた画像を表示するにはシンボリックリンクを作成する必要があります。

シンボリックを作成することでプロジェクト直下のpublicディレクトリからstorageディレクトリにアクセスできるようになります。

$ php artisan storage:link

これでアップロードした画像ファイルにstorage/ディレクトリ/ファイル名でアクセスすることができるようになります。

画像パスを保存する際にstorage/ディレクトリ/ファイル名として保存したのはこのためです。

画像を表示する

画像ファイルを表示する際には、bladeファイルで下記のように記述することで表示することができます。

<img src="{{ asset($image->path) }}">

asset関数を用いることでドメイン名からのパスを取得することができます。

ブラウザにアクセスして確認してみましょう。

無事にアップロードした画像が表示されていますね。

まとめ

Laravelで画像をアップロードして表示する方法を紹介してきました。

今回はstoreメソッドやstoreAsメソッドを利用して画像の保存を行いましたが、LaravelにはStorageファサードがあり、こちらを使ったファイル操作もとても便利です。

Storageファサードについてはまた別の記事で紹介しよう思います。

-PHP/Laravel, プログラミング

Copyright© みぎさんドットコム , 2022 All Rights Reserved Powered by STINGER.