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

2017.9.29 (金)

通常の文字列のポストは普通にできるんですが、ファイルのアップロードはちょっと特殊(便利)です。というのはLaravelにはFILE_SYSTEMとかstrageというものがあって、別ホストの領域をLaravelの中に取り込めるという仕組みがあります。つまりアップロードしたファイルは大容量ストレージ(S3とか)にアップロードできてしまうわけです。
なので、生PHPに慣れ親しんだファイルアップロードとはおよそ扱いがちがっているということになっています。

画像が保存される場所の確保

アップロードファイルが保存される領域を設定します。Laravelのこのシステムはとても便利でこのストレージ領域をS3などに設定することが可能になってます。NFSファイルマウントをこの領域に設定しちゃうとかいろいろできます。楽ですね。

config/filesystems.php

にファイルを保存する場所を指定する設定があります。.envのデフォルトはlocalになっていますが、publicに変更して、

'disks' => [

    'local' => [
        'driver' => 'local',
        'root' => storage_path('app'),
    ],

    'public' => [
        'driver' => 'local',
        'root' => storage_path('app/public'),
        'url' => env('APP_URL').'/storage',
        'visibility' => 'app/public',
    ],
   ....

が適用されるように変更します。app/public以下をストレージとして認識するようになります。
ストレージはいろんな種類のものを設定できるので実運用の際はとても便利です。
Laravel 5.5 ファイルストレージ

アップローダーの作成

アップローダーは通常の文字列のPOSTと同じように作成します。

// view

<form action="/store" enctype="multipart/form-data" method="post"><input name="photo" type="file" /></form>

フォームビルダーを使うのでもいいです。

コントローラ側では、

// controller
public function store(Request $request)
{
    $originalPath = "app/".$request->file('file')->store('public/pics');
    // ....
    // $originalPathの保存とかする
    // ....
    return true;
}

という感じで、画像を保存します。リクエストで受け取った情報を指定のオブジェクトで受けて保存します。このときに先に設定したストレージの指定を行っています。
Laravel 5.5 HTTPリクエスト アップロードファイルの保存
この場合はアップロードしたファイルが、

storage/app/public/pics/xxxxxxx.jpg

のような感じで保存されます。filesystems.phpの情報が関連してくるのでややこしいですが、慣れると快適。
私の環境ではパーミッションを777にしておかないとダメだったけど、Apacheが動いてくれていたのでそこらあたりも自分で調節してみてください。またjpgがjpegとして保存されるのだけど、ここ何とかした方がいいかもです。
ここまでが基本的な流れです。

ファイルの公開

このストレージはDocumentRootじゃないところに保存されているので、公開する際にはDocumentRoot以下にシンボリックリンクを作成します。

php artisan storage:link

public/storage/にシンボリックリンクが作成されて、以下のようにするとWEB上からアクセスできるようになります。

env('APP_URL').public/storage/pics/xxxxxxx.jpg

  • アップロードするファイル名を取得するため、getClientOriginalName()を使う
  • アップロードするファイルの一時的な名を取得するため、getFilename()を使う
  • アップロードされたファイルのパスを取得の場合、getRealPath()を使う
  • アップロードされたファイルのサイズを取得の場合、getClientSize()を使う
  • アップロードされたファイルのmimeタイプを取得の場合、getClientMimeType()を使う
  • アップロードされたファイルの拡張子を取得の場合、getClientOriginalExtension()を使う
  • move()メソッドはファイルを記載したパスまで移動するために使います。ファイルパスはパラメーター1とファイル名はパラメーター2で記載する必要があります。


Laravel 5.4 ファイルストレージ