Laravelでファイルをデータベースで管理するライブラリを公開した
今回はLaravel上で簡単にファイルをデータベースで管理できるようにするライブラリを公開したので紹介したいと思います。
laravel-eloquent-storage
このライブラリはEloquentモデルに
<?php use MatchinGood\EloquentStorage\EloquentStorage; class UserFile extends EloquentStorage { }
という感じで継承させるだけで、そのモデルでファイルを管理できるようになります。
仕組み
データベースにファイルを保存するのはデータベースの容量を圧迫するだけでなくパフォーマンスにも影響が出てきます。
なので、容量単位の単価がはるかに安いS3にファイルを保存するようにしました。このライブラリではこの辺りのファイル管理を隠蔽しています。
概念的には以下の図で表せます。
S3にはファイル名の衝突を避けるためにユニークなファイル名で保存し、MySQLには保存したユニークなファイル名とオリジナルのファイル名を保存します。
これにより、ファイル名の衝突を避けつつダウンロード時にはオリジナルのファイル名を使うことができます。
実際に使うと
例えばユーザーがアップロードしたファイルをUserFileというモデルで保存しようと思った時は
<?php $file = $request->file('file'); $userFile = new UserFile; $userFile->saveFromUploadedFile($file);
たったこれだけでファイルを保存することができました。さらにそのファイルをダウンロードさせようと思ったらコントローラで、
<?php $userFile = UserFile::find(1); return response()->downloadEloquentStorage($userFile);
とするだけでダウンロードさせることができます。これはResponse Macro
をサービスプロバイダーで定義することでdownloadEloquentStorage
という関数を使うことができるようになっているからです。
開発環境時の工夫
システムを開発時にS3に繋げたくありません。そこでconfig/eloquentstorage.php
でドライバーを設定することができるようになっています。
<?php return [ // this is the same drivers as Storage facade on Laravel // ELoquentStorage uses Storage facade internally 'driver' => 'local' ];
このライブラリは内部的にはStorage
を使っているので、S3にあげたくない場合はドライバーをlocal
にすることでローカル環境にファイルを保存します。
実際にデプロイするときにこのドライバーをs3
とすることでS3に保存できるようになります。
まとめ
最近弊社では積極的にオープンソースのライブラリを公開してコミュニティに貢献しようという熱が高まってきました。このような軽量なものから、まだ公開していない大きなライブラリまであります。このような環境はエンジニアにとってはとても魅力的な環境であると考えているからこそ実践させてもらっています。