#17 Laravel基礎
ファイルアップロードとストレージ
ファイルアップロードの仕組み
ストレージ? ファイルの保存・取得を管理する仕組み。ローカルディスクやS3などを切り替え可能な統一APIで操作できる。 はファイルの保存・取得・削除を統一したAPIで操作できるLaravelの機能です。ローカルディスクやAmazon S3など複数のドライバーを切り替えられます。
フォームでファイルを受け取る
フォームには enctype="multipart/form-data" が必要です。
{{-- 📁 resources/views/posts/create.blade.php --}}
<form method="POST" action="{{ route('posts.store') }}" enctype="multipart/form-data">
@csrf
<input type="text" name="title">
<textarea name="body"></textarea>
<input type="file" name="thumbnail">
<button type="submit">投稿する</button>
</form>
コントローラーでファイルを処理する
// 📁 app/Http/Controllers/PostController.php
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'body' => 'required',
'thumbnail' => 'nullable|image|max:2048', // 2MBまでの画像
]);
$thumbnailPath = null;
if ($request->hasFile('thumbnail')) {
// storage/app/public/thumbnails/ に保存
$thumbnailPath = $request->file('thumbnail')
->store('thumbnails', 'public');
// 戻り値は "thumbnails/xxxx.jpg" のようなパス
}
Post::create([
'title' => $request->title,
'body' => $request->body,
'thumbnail_path' => $thumbnailPath,
'user_id' => auth()->id(),
]);
return redirect()->route('posts.index');
}
ストレージのディスク設定
// 📁 config/filesystems.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app/private'),
// ブラウザからは直接アクセス不可
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
// php artisan storage:link でpublic/storageからシンボリックリンクを張る
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
],
],
public ディスクに保存したファイルをブラウザからアクセスできるようにするには:
php artisan storage:link
これで public/storage → storage/app/public のシンボリックリンクが作られます。
ファイルのURLを取得する
// public ディスクのファイルURL
$url = Storage::disk('public')->url($post->thumbnail_path);
// → https://example.com/storage/thumbnails/xxxx.jpg
// ビューで使う
asset('storage/' . $post->thumbnail_path)
// または
Storage::url($post->thumbnail_path)
ファイルの操作
use Illuminate\Support\Facades\Storage;
// 存在確認
Storage::disk('public')->exists('thumbnails/abc.jpg'); // true/false
// ファイルを削除
Storage::disk('public')->delete($post->thumbnail_path);
// ファイルを移動・コピー
Storage::move('old/path.jpg', 'new/path.jpg');
// ファイルの中身を取得
$contents = Storage::get('private/report.pdf');
// ファイルに書き込む
Storage::put('reports/today.txt', $content);
ファイル更新時の古いファイル削除
投稿のサムネイルを更新するときは、古いファイルを削除しましょう。
// 📁 app/Http/Controllers/PostController.php
public function update(Request $request, Post $post)
{
$data = $request->only('title', 'body');
if ($request->hasFile('thumbnail')) {
// 古いファイルを削除
if ($post->thumbnail_path) {
Storage::disk('public')->delete($post->thumbnail_path);
}
// 新しいファイルを保存
$data['thumbnail_path'] = $request->file('thumbnail')
->store('thumbnails', 'public');
}
$post->update($data);
return redirect()->route('posts.show', $post);
}
まとめ
- フォームに
enctype="multipart/form-data"が必要 $request->file('field')->store('フォルダ', 'disk')でファイルを保存するphp artisan storage:linkでpublicディスクのファイルをWebから公開できるStorage::url()でファイルのURLを取得できる- ファイル更新時は古いファイルを
Storage::delete()で削除する
次回はConfigとenvを使った設定管理を学びます。