概要
たとえば保存されたアップロードファイルなど、storage
ディレクトリー下に保存したファイルのパスを取得する手順を整理する。
storage/app/public
直下またはそのサブディレクトリー下に保存されたファイルを対象とするartisan
により、storage/app/public
へのシンボリックリンクstorage
をpublic
ディレクトリー下に作成public
ディレクトリー内は公開されるので、以下のいずれかの方法でURLを取得asset()
ヘルパーやurl()
ヘルパーの引数に'storage/' . $path
を与えてURLを取得\Storage::url()
の引数に$path
を与えてドキュメントルート以下のパスを取得
公開領域
Laravelのファイルの公開場所は以下の様になっている。
public
ディレクトリー下のファイル、あるいはそのサブディレクトリー下のファイルは公開対象- URLでの指定方法は、
public
ディレクトリー下のディレクトリー・ファイル構成をドメイン名に続けて指定
たとえば以下の例では、public
ディレクトリー下にサブディレクトリーtest
があって、その下にbar.txtファイルがある。
1 2 |
$ cat public/foo/bar.txt サンプルテキスト |
このファイルは公開されていて、このアプリケーションをlocalhostで確認する場合、ブラウザーで以下のようなURLを指定するとファイルの内容がブラウザーに表示される。
1 |
localhost:3000/foo/bar.txt |
storage下のファイルの公開
以下のコマンドを実行すると公開領域にシンボリックリンクstorage
が作成され、それがstorage/app/public
ディレクトリーを指す。
1 |
php artisan storage:link |
public
ディレクトリー下にシンボリックリンクstorage
が作成される- リンク
storage
はstorage/app/public
を指す - ディレクトリー下にアクセスするURLは以下のとおり
ドメイン名/storage/....
1 2 3 4 5 6 7 8 9 10 |
$ php artisan storage:link The [public/storage] directory has been linked. $ ls -Al public 合計 16 -rw-rw-r--. 1 vagrant vagrant 593 9月 7 20:19 .htaccess -rw-rw-r--. 1 vagrant vagrant 0 9月 7 20:19 favicon.ico -rw-rw-r--. 1 vagrant vagrant 1823 9月 7 20:19 index.php -rw-rw-r--. 1 vagrant vagrant 24 9月 7 20:19 robots.txt lrwxrwxrwx. 1 vagrant vagrant 70 10月 21 21:15 storage -> /home/..../アプリケーション/storage/app/public -rw-rw-r--. 1 vagrant vagrant 1194 9月 7 20:19 web.config |
たとえばアプリケーションがlocalhostで稼働している場合、storage/app/public/foo/bar.png
にアクセスするURLは以下のとおり。
1 |
localhost:3000/storage/foo/bar.png |
画像ファイルを表示する例
コントローラー
アップロードファイルの保存で保存された画像ファイルを表示させる例を示す。
画像ファイルをフォームで選択してPOSTすると、コントローラーのstore
アクションにルーティングされるとする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests\ImageRequest; class ImageController extends Controller { public function index() { return view('images.index'); } public function store(ImageRequest $request) { // 一時保存されたUploadedFileの取得 $image = $request->file('image'); // ファイルの保存と保存されたファイルのパス取得 $path = ''; if (isset($image)) { $path = $image->store('images', 'public'); } return view('images.index', ['path' => $path]); } } |
コントローラーの処理は以下の通り。
store
アクションで、フォームリクエストからファイルオブジェクトを取得- 画像ファイル本体を
public
ディスクのimages
ディレクトリーに保存 - その際、ランダム文字列で生成されるファイル名が戻り値となり、これを
$path
に保存 $path
を渡してimages.index
ビューをレンダリング
ビュー
ページを表示するテンプレートは以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html lang="ja" dir="ltr"> <head> <meta charset="utf-8"> <title>画像選択</title> </head> <body> <h1>画像選択</h1> <form method="post" action="{{ route('images.store') }}" enctype="multipart/form-data"> @csrf <input type="file" name="image"> <input type="submit" value="登録"> </form> {{-- バリデーションエラー表示 --}} @foreach ($errors->all() as $error) <p>{{ $error }}</p> @endforeach {{-- 画像ファイルのURLと画像を表示 --}} @isset ($path) <p>{{ $path }}</p> <p>{{ asset('storage/' . $path) }}</p> <p>{{ url('storage/' . $path) }}</p> <p>{{ \Storage::url($path) }}</p> <img src="{{ asset('storage/' . $path) }}"> <img src="{{ url('storage/' . $path) }}"> <img src="{{ \Storage::url($path) }}"> @else <p>ファイルはアップロードされていません</p> @endisset </body> </html> |
ファイル関係の表示は後ろの方で、$path
の内容とasset()
、url()
2つのヘルパーの結果を表示し、ヘルパーで生成されたURLで画像を表示させている。
$pathの内容
画像ファイルを保存した後の$path
の内容は以下の通りで、store
アクションでの処理により、images/ランダム文字列によるファイル名
となっている(拡張子はそのまま)。
1 |
images/kn2NdjJUL9k20kE0xLhmTwAZcFycySvLcFcLkybz.jpg |
asset(), url()によるURL
ファイルは公開領域のstorage
ディレクトリーから参照されるが、そのURLはasset()
、url()
の何れでも同じ結果を与える。
1 2 |
http://localhost:3000/storage/images/kn2NdjJUL9k20kE0xLhmTwAZcFycySvLcFcLkybz.jpg http://localhost:3000/storage/images/kn2NdjJUL9k20kE0xLhmTwAZcFycySvLcFcLkybz.jpg |
\Storage::url()によるドキュメントルート下のパス
\Storage
ファサードのurl()
メソッドに$path
を指定すると、ドキュメントルート下の画像ファイルのパスが得られる。
1 |
/storage/images/Sa6Oicpvoma4j53WCbZcyaICusRvxYzwZvhNBMX4.jpg |
img要素のsrcの指定
先のビューでは、asset()
、url()
、\Storage::url()
の結果をimg
要素のsrc
の値に指定していて、いずれも同じ画像が表示される。