Larave5.5のfilesystemを使って画像をアップロードしたり参照したりする方法を調べる

# filesystemとかいうやつ
先日、画像をアップロードしようとしたところ、laravelにはそういう機能があるらしいことを知りました。

- [Laravel5.5で個別に選択した複数の画像をアップロードする処理 - Qiita](https://qiita.com/ragingalpaca/items/851b0201b40075e39349)

`->store`とかそういうやつ。

以前作ったやつではfwriteとかそんな感じでやった覚えがあるのですが、まあそういうのがあるならわざわざ自力で実装する理由もないですよね。

というわけで真似しようとしてみたのですが、ちょっとよくわからなくなりました。

## わからんポイント
上記の記事で参考にした記事では、filesystemとかいうやつの設定を書き換えて、保存先を指定してました。
デフォルトで指定されるlocalのパスを、publiｃに変更する方法ですね。

まあ確かに、それで保存できるんですが、ひとつ問題が。
その場所を読み出す方法がわからないという。

もちろん直接指定する事はできますが、わざわざstoreとかしてるんだからgetとか使いたいのが人情です。

## できたはできたけど
以下のようにすればとりあえず指定はできました。
pathには、storeの戻り値が格納されています。

```php:画面側
{{ url(Storage::disk('local')->url($image->path)) }}
```

```php:filesystem
    'disks' => [

        'local' => [
            'driver' => 'local',
//            前回変更した部分
//            'root' => storage_path('app'),
            'root' => public_path('img'),
            // 追加
            'url' => env('APP_URL').'/img',
        ],

```

できたんですが……

**そもそもlocalって書いてあるし、publicってのが別にあるみたいだし、なんていうか使い方間違えてるのでは……？**

ってなったので調べてみました。

## 参考資料
[ファイルストレージ 5.5 Laravel](https://readouble.com/laravel/5.5/ja/filesystem.html)
[それはそれは素晴らしい『Laravel』のファイルシステムについて語りたい | 東京上野のWeb制作会社LIG](https://liginc.co.jp/355887)


# 読み書きする場合は（普通は）publicを使う？
あたりまえ体操とかするレベルで当たり前なんですがやはりpublicを使うっぽい雰囲気があります。

ただし準備は必要で、シンボリックリンクを作成する必要があるとのこと。
`php artisan storage:link`でデフォルトなシンボリックリンクが作成されます。
public直下のstorageから、storage/app/publicを指定するリンクなので、それ以外に飛ばしたい場合は別途シンボリックリンクを作成する必要があります。

```bash:
cd public
ln -s ../storage/app/public storage
```

デフォルトと同じシンボリックリンクの作成はこんな感じかな？

というわけで作法的にはプロジェクトファイル/storage/app/publicに保存されるのが正解のようです。
disks => public => rootですね。

で、urlを指定すると disks => public => urlで指定されているpublic/storageが指定される。

ブラウザからpublic/storageにアクセスすると、シンボリックリンクでstorage/app/publicに向き先が変わると。

## 書き方
呼び出し方は、localをpublicに変えるだけ。

```php:publicを呼ぶとき
{{ url(Storage::disk('public')->url($image->path)) }}
```

保存するときは、storeの引数にpublicの指定を追加してやる必要があるようです。

```php:publicに保存するとき
$image->store('', ['disk' => 'public']);
$image->storeAs('', 'hoge.jpg', ['disk' => 'public']);

```

## 実験
早速使ってみることにします。

### 前準備
まずはfilesystemを書き換えました。

```php:filesystem.php
        'public' => [
            'driver' => 'local',
//            'root' => storage_path('app/public'),
//            'url' => env('APP_URL').'/storage',
            'root' => storage_path('app/public/img/upload'),
            'url' => env('APP_URL').'/img/upload',
            'visibility' => 'public',
        ],
```

次にシンボリックリンクを作成します。
それまで作成していたpublicのuploadフォルダには申し訳ありませんが消えてもらいます。
migrateもやり直します。

```bash:homestead
vagrant@homestead:~/code/Laravel$ cd public/img/
vagrant@homestead:~/code/Laravel/public/img$ ln -s ../../storage/app/public/img/upload upload
vagrant@homestead:~/code/Laravel/public/img$ ls -l
total 488
lrwxr-xr-x 1 vagrant vagrant     35 Jun 19 10:16 upload -> ../../storage/app/public/img/upload

```

### 保存処理
storeを変更し、向き先をpublicにしました。

```php:コントローラー
$path = $e->store('', ['disk' => 'public']);
```

filesystemだとdisksだけどここはdiskなんですね……わかるような気はしますが紛らわしい。
というか間違えました。

ともあれ、これでpublicのrootである`storage/app/public/img/upload`（無駄に深い）に保存されるようになりました。

### 読込処理
これについては前述のとおり、

```php:画面で
{{ Storage::disk('public')->url($image->path) }}

```

でいけます。
filesystemの記載方法によりますが、publicのurlには`env('APP_URL')`が使われていたため`url()`も不要でした。


# そんな感じ？
ざっと調べただけなんで、理解が間違ってるかも……などと言い訳しつつ。

とりあえずそんな感じです。
s3とかはよくわからないです。