Spatie Laravel Media Library: Laravelでのファイル・メディア管理(拡張版)
I. はじめに
現代のLaravelプロジェクトでは、ファイルやメディアの管理は単なるアップロードだけでは済みません。以下のニーズが一般的です:
- 画像、動画、PDFなどの多様なファイルタイプを扱う
- サムネイル生成、リサイズ、ウォーターマークなどの変換
- 複数コレクション・マルチディスク管理
- Queueを使った非同期処理でパフォーマンス最適化
- API/SPAで安全にアクセス可能
Spatie Laravel Media Library はこれらを一元管理できる強力なパッケージです。データベースには media テーブルを用意し、ファイルごとのメタデータ(名前、パス、サイズ、MIMEタイプ、コレクション名、ディスク名、カスタムプロパティ)を保存します。
Note: メタデータを保存することで、後から検索、タグ付け、アクセス権管理、統計取得が容易になります。
II. 基本インストールと設定
1. パッケージのインストール
composer require spatie/laravel-medialibrary
Tip: 最新バージョンを確認してインストールすると、新機能とバグ修正を享受できます。
2. マイグレーションと設定の公開
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="config"
php artisan migrate
Alert: migrate前に必ずバックアップ。既存の
mediaテーブルがある場合、競合が発生する可能性があります。
3. ModelへのTrait追加
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Product extends Model implements HasMedia
{
use InteractsWithMedia;
}
Tip:
HasMediaを実装することで、addMedia や getMediaUrl などの便利メソッドが使用可能になります。
III. ファイルアップロードと変換
1. 基本アップロード
$product->addMedia($request->file('image'))
->toMediaCollection('images');
Tip: バリデーションを追加して、許可されたMIMEタイプとサイズのファイルのみをアップロードすることが推奨です。
2. サムネイル変換
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(200)
->height(200)
->nonQueued(); // 同期処理の場合
}
Tip: 大量変換の場合はQueueに登録し、Webリクエストをブロックしないようにしましょう。
3. URL取得
$product->getFirstMediaUrl('images'); // オリジナル
$product->getFirstMediaUrl('images', 'thumb'); // サムネイル
IV. 複数コレクションとマルチディスク管理
1. 複数コレクション
$product->addMedia($request->file('main_image'))
->toMediaCollection('images');
$product->addMedia($request->file('banner'))
->toMediaCollection('banners');
2. マルチディスク
$product->addMedia($request->file('high_res'))
->toMediaCollection('hires', 's3');
$product->addMedia($request->file('thumbnail'))
->toMediaCollection('thumbnails', 'local');
Tip: S3やGCSなど外部ディスクを使うとストレージコストを最適化できます。
V. メタデータとカスタムプロパティ
$product->addMedia($request->file('image'))
->withCustomProperties([
'uploaded_by' => auth()->id(),
'tags' => ['new', 'sale']
])
->toMediaCollection('images');
- プロパティでの検索
$images = $product->getMedia('images')
->filter(fn($media) => in_array('sale', $media->custom_properties['tags']));
Tip: タグやユーザーIDでフィルタリングすることで、管理画面や分析に役立ちます。
VI. Queueを使った非同期処理
$media = $product->addMedia($file)
->toMediaCollection('images');
$media->registerMediaConversionsUsingQueue();
Best Practice: Queueで変換処理を行うことで、リクエストレスポンスが高速化し、大量ファイルも安全に処理できます。
VII. 自動クリーンアップとPrune
php artisan media-library:clean
$schedule->command('media-library:clean')->daily();
Tip: Schedulerと組み合わせることで不要ファイルを自動削除し、ディスク容量を最適化できます。
VIII. 負荷テストとスケーリング
1. 複数ファイル同時アップロード
$files = $request->file('images');
foreach ($files as $file) {
$product->addMedia($file)
->toMediaCollection('images');
}
2. Best Practice
- Queueで変換処理
- S3使用時、5MB以上はmultipart upload
- プリサインURLで直接S3アクセス
- コレクションをhot/cold storageに分割
- HorizonでWorkerを自動スケール
Note: 本番前に負荷テストを行い、変換処理がボトルネックにならないか確認してください。
IX. API / SPAでの利用
return response()->json([
'images' => $product->getMedia('images')->map(fn($media) => $media->getUrl())
]);
- Lazy-load画像で帯域を節約
- プリサインURLでセキュアにアクセス可能
Tip: SPAの場合、フロント側でキャッシュを使うとレスポンスをさらに高速化できます。
X. 総合ベストプラクティス
- コレクションを種類ごとに明確に分ける
- マルチディスクでストレージとコストを最適化
- 重い変換はQueueで処理
- 詳細なメタデータを保存して追跡可能に
- SchedulerでPruneして不要ファイルを防ぐ
- S3はキャッシュ/プリサインURL活用
- 本番前に大量ファイルで負荷テスト
- HorizonでWorkerを自動スケール
Tip: これらを守ることで、スケーラブルでメンテナンスしやすいメディア管理システムを構築できます。
XI. まとめ
Spatie Laravel Media Library は Laravel向けのプロフェッショナルなメディア管理ソリューション です:
- ファイル管理、変換、コレクション、多ディスク対応
- 詳細なメタデータと柔軟なクエリ
- Queue + Horizonで大規模プロジェクトも対応
- API / SPAへの統合も簡単
- ベストプラクティスでコストとパフォーマンスを最適化
Conclusion: Laravelプロジェクトでメディア管理を本格的に行うなら必須パッケージです。