Laravelにはファイル操作にはStorageという便利な機能が備わっています。Storageを使えばローカルのファイルもリモートのファイルも同じ方法で操作を行うことができるので、もし使い慣れていないようならばこの機会にStorageの使い方をマスターしておきましょう。

LaravelのStorageとは

LaravelのStorageはFlysystemのfilesystemライブラリを利用して作られています。

Storageを利用すれば、ローカルディスクも外部のFTPサーバもクラウドのAmazon S3もLaravelのアプリケーションから見れば同じものとして扱うこと(各接続デバイスの違いを吸収してくれる)ができ、同じメソッドを使ってファイル操作・ディレクトリ操作を行うことができます。

storageを使う場合と使わない場合
storageを使う場合と使わない場合

言葉よりも実際にFTPサーバへの接続を通して、Storageがどれほど便利なのか確認していきます。

FTPを使ってファイル一覧を取得

Storageがどのようなものか理解するためにFTPを使ってFTPサーバ上にあるファイルの一覧を取得します。

Storageはconfig/filesystems.phpを通して設定を行うので、FTPの接続情報をこのfilesystem.phpに記述する必要があります。

filesystems.phpのdisksプロパティに新規にftpを追加します。host, username, passwordは各環境に合わせた値を設定します。


  'disks' => [
        'ftp' => [
            'driver'   => 'ftp',
            'host'     => 'XXXXXX',
            'username' => 'XXXXXX',
            'password' => 'XXXXXX',
        ],
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

これでFTPを利用するための設定は完了です。下記のようにオプショナル設定もあります。


  'disks' => [
        'ftp' => [
            'driver'   => 'ftp',
            'host'     => 'XXXXXX',
            'username' => 'XXXXXX',
            'password' => 'XXXXXX',
            // Optional FTP Settings...
            // 'port'     => 21,
            // 'root'     => '',
            // 'passive'  => true,
            // 'ssl'      => true,
            // 'timeout'  => 30,
        ],

tinker上でStorageのfilesメソッドを使ってFTPサーバ上のファイル一覧を取得します。実行すると下記のようにfilesメソッドでFTPサーバ上のファイル一覧を取得することができました。

簡易的な動作確認を行うためにtinkerを利用しています。直接Controllerに記述して動作確認も可能です。その場合はuse Illuminate\Support\Facades\Storageが必要になります。

 $ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> Storage::disk('ftp')->files();
=> [
     ".bash_profile",
     ".bash_history"
   ]

diskメソッドには、filesystem.phpのdisksプロパティにある値(ドライバ)によって接続先を変えることができます。

Laravelのローカルディスクに保存されているファイル一覧を取得する場合は、diskメソッドにlocalを入れるだけでファイル一覧を取得することができます。


>>> Storage::disk('local')->files();
=> [
     ".DS_Store",
     ".gitignore",
     "Laravel_send_email.png",
     "zxpitPfr5KXTNROYPBS7lqJIMkLHH99mbmR82oE2.png",
   ]

このようにdiskメソッドをftpからlocalに変更するだけで, 同じfilesメソッドを使ってファイル一覧を取得することができます。もしStorageがなければ、FTPサーバに接続する際はftp_connectを記述していたかもしれません。しかしStorageを使えばファイルの保存場所を気にすることなく同じ方法でファイルを操作することができます。

Storageの設定について

Storageの設定はfilesystem.phpで行います。先程、diskメソッドを使ってlocalとftpの切り替えを行いましたが、デフォルト値が決まっており、.envファイルにFILESYSTEM_DRIVERがなければ、localが設定されます。デフォルトを変更したい場合は、.envファイルにFILESYSTEM_DRIVERを追加し変更したいドライバ値を設定します。


'default' => env('FILESYSTEM_DRIVER', 'local'),

デフォルト値を使用する場合は、diskメソッドをつける必要がなくファイル一覧を取得する場合は、Storage::files()で実行することができます。

Laravelインストール直後では3つのドライバの情報がfilesystems.phpに記述されています。localとpublicとs3です。localとpublicはLaravelのローカルディスクのドライバで、s3はAmazonのs3を使用する場合に使うドライバです。

localではappをルートディレクトリとしてappディレクトリ以下のファイルやディレクトリを操作します。publicは外部からアクセス可能なapp/publicをルートディレクトリとしてそれ以下のファイル、ディレクトリを扱います。

ファイルを保存する時にパスを設定しますが、もしパスを設定しなければ保存したファイルはルートディレクトリの直下に保存されます。

'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
    'bucket' => env('AWS_BUCKET'),
    'url' => env('AWS_URL'),
],

Storageによるファイル操作

FTPサーバ上とローカルのファイルの操作を通して、Storageが非常にパワフルなツールであることが理解できたと思うので、ファイル操作のメソッドを確認していきます。ここから先はdiskの設定のドライバの値には依存しません。つまり、ローカルディスクでもs3でも同じ操作です。

使用したいメソッドはFilesystemAdaper.phpクラスに記述されているので、APIマニュアルから確認できます。

メソッドの一覧

使用頻度が高いと考えられるもののみ抜粋しています。

  • get(‘logo.jpg’) : ファイルを取得します
  • put(‘logo.jpg’, $fileContent) : ファイルを保存します。
  • putFile(PATH, $file) : 指定したPATHにファイルを保存。名前は一意のIDです。
  • putFileAs(PATH, $file, ‘logo.jpg’) : 指定したPATHにlogo.jpgという名前ファイルを保存します。
  • exists(‘logo.jpg’) : ファイルが存在するかチェックを行います。あればtrueが返されます。
  • copy(‘logo.jpg’, ‘new_logo.jpg’) : ファイルのコピーを行います。
  • move(‘logo.jpg, ‘new_logo.jpg’) : ファイルの移動を行います。
  • delete(‘logo.jpg’) : ファイルの削除を行います。
  • makeDirectory(‘image’) : ディレクトリを作成します。
  • deleteDirectory(‘image’) : ディレクトリを削除します。
  • size(‘logo.jpg’) : ファイルのサイズを確認します。
  • files(‘public’) : publicディレクトリにあるファイルのみ表示します。
  • allFiles(‘public’) : publicディレクトリ以下のすべてのファイルとディレクトリを表示します。ファイル、ディレクトリがたくさんある場合は時間がかかります。
  • path(‘logo.jpg’) : ファイルのフルパスを表示します。ファイル名をfalseにするとrootパスが表示されます。

メソッドだけでは使用方法がわからないので、ファイルの保存と削除を通してメソッドの使用方法を確認します。

ファイルの保存

アップロードしたファイルをStorageを使用して保存します。保存には、名前がLaravelでユニークなIDが自動で振られるputFileとファイル名を指定できるputFileAsがあります。


$file_name = $request->file('file')->getClientOriginalName();

$path = Storage::putFile('',$request->file('file'));

$path_as = Storage::putFileAs('',$request->file('file'), $file_name);

ファイルの保存先(root設定)

localドライバとpublicドライバの保存場所はfilesystems.phpで設定されており、各ドライバのrootの設定で確認することができます。localはappでpublicはapp/publicディレクトリ下に保存されます。


'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

ftpドライバの場合は、ftpで接続した先のディレクトリが保存先になります。

visibilityとは

filesystems.phpのpublicドライバの設定でvisibilityという設定値があります。visibilityによりパーミッションの設定を行うことができます。publicとprivateの2つの値を取り、MAC環境ではpublicでは644の設定、privateでは600の設定になります。


'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

ファイルを保存する時には、下記のようにpublicとprivateを設定することができます。


$path = Storage::putFile('',$request->file('file'),'public');
$path = Storage::putFile('',$request->file('file'),'private');

urlとは

filesystems.phpのpublicドライバの設定でurlという設定値があります。Storage::url($file_path)で利用することができ、指定したファイルのURLを表示させることができます。


'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

例えばapp/publicディレクトリの下にimagesディレクトリを作成し2つのファイルを保存します。filesメソッドでファイルの一覧を取得した後にurlを使うと外部からアクセス可能なURLを取得することができます。


$files = Storage::disk('public')->files('images');

foreach( $files as $file){
	echo Storage::disk('public')->url($file).'
'; }

一覧の処理で画像が保存されているURLを表示させることができます。


http://localhost/storage/images/Laravel_send_email.png
http://localhost/storage/images/Laravel_storage.png

ファイルの削除

ファイルの削除は削除したいファイルのパスを設定します。複数の場合は配列を使って削除することができます。


Storage::delete('public/laravel_logo.png');

Storage::delete(['public/laravel_logo.png','public/vue_logo.png']);