Laravel ファイルのアップロード

アップロード機能の手順

  1. テーブル(カラム)を用意する
  2. アップロード先を設定する
  3. フォームを作成する
  4. アクションを作成する

テーブル(カラム)を用意する

テーブルにはVARCHARなど文字列型のカラム(例:file_nameカラム)を用意し、ファイル名やファイルパスの保存に使う。

アップロード先を設定する

Laravelでは、アップロードされたファイルの保存先はconfig/filesystems.phpファイルに設定されている。

保存先
'local ' storage/appフォルダ
'public' storage/app/publicフォルダ
's3' Amazon S3(接続先は.envファイルの環境変数で設定)

保存先を変更する場合、'default'キーに設定されている環境変数FILESYSTEM_DISKの値を.envファイルで編集します。デフォルトはFILESYSTEM_DISK=localなので、保存先はstorage/appフォルダになります。

フォームを作成する

ビューファイル内でアップロード用のフォームを作成します。重要なのは以下の2点です。 1. form要素にenctype="multipart/form-data"を設定し、ファイルも一緒に送信できるようにする 1. input要素にtype="file"を設定し、ファイルをアップロードするための入力欄を作成する 例

<form action="送信先のURL" method="POST" enctype="multipart/form-data">
    @csrf
    <input type="file" name="image">
    <input type="submit" value="アップロード">
</form>

アクションを作成する

コントローラのアクション(store、updateなど)では、主に以下の処理を行います。 1. アップロードされたファイルをRequestインスタンスのfile()メソッドで取得する 1. 取得したファイルをstore()メソッドで保存する 1. 保存先のファイル名やファイルパスをテーブルに保存する 例

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SampleController extends Controller
{
    public function store(Request $request) {
        $sample = new Sample();

        // アップロードされたファイル(name="image")をstorage/app/samplesフォルダに保存し、戻り値(ファイルパス)を変数$image_pathに代入する
        $image_path = $request->file('image')->store('samples');

        // ファイルパスからファイル名のみを取得し、Sampleインスタンスのimage_nameプロパティに代入する
        $sample->image_name = basename($image_path);

        $sample->save();

        return redirect('/samples');
    }    
}
  • file()メソッドの引数:取得するファイルに対応するname属性の値
  • store()メソッドの引数:config/filesystems.phpファイルに設定した保存先(デフォルトはstorage/appフォルダ)より後のパス
    store()メソッドの戻り値は保存先のファイルパスなので、上記のサンプルコードのように変数($image_path)に代入しておくことで、その後の処理に使えます。

basename()はパスからファイル名を取得するPHPの関数です。例えば引数に'samples/sample.jpg'を渡した場合、戻り値は'sample.jpg'になります。

上記のサンプルコードのように、ファイル名を保存したい場合はとても便利な関数です。

アップロードしたファイルの表示方法

  1. シンボリックリンクを作成する(シンボリックリンクについては後述)
  2. ファイルのURLを取得する

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

storage/app/publicフォルダへのシンボリックリンクpublic/storageフォルダに作成

sail artisan storage:link

アップロードされたファイルのデフォルトの保存先はstorage/appフォルダです。

しかし、Laravelではstorageフォルダ以下のファイルは外部に公開することができません。Laravelで外部に公開できるのは、publicフォルダ以下のファイルのみです。

そこで、storage/app/publicフォルダへのシンボリックリンクをpublic/storageフォルダに作成し、storage/app/publicフォルダ以下のファイルを参照することで、間接的にファイルを公開します。

ファイルのURLを取得

ビューファイル内でasset()ヘルパ関数を使い、ファイルのURLを取得すればOKです

<img src="{{ asset('storage/samples/' . $sample->image_name) }}" alt="アップロードした画像ファイル">
// http://example.com/public/s

asset('ファイルパス')はpublicディレクトリのパスを返す関数

.envと合わせて

asset()関数は、現在のリクエストのスキーマ(HTTPかHTTPS)を使い、アセットへのURLを生成します。
.envファイルのASSET_URL変数で、アセットURLホストを設定できます。

// ASSET_URL=http://example.com/assets

$url = asset('img/photo.jpg'); // http://example.com/assets/img/photo.jpg