LaravelのStrorageクラスでは、copy()メソッドでファイルをコピーすることができます。ですが、これはコピー元と先が同じdisk定義されている必要があります。
この記事では、異なるdisk間でファイルをコピーする方法を説明します。
前提
config/filesystem.phpで下記のdisk定義が行われているとします。ここではsrcがコピー元、destがコピー先のディスクであるとします。
<?php
return [
'default' => env('FILESYSTEM_DRIVER', 'local'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
// コピー元ファイルが存在する場所
'src' => [
'driver' => 'local',
'root' => storage_path('src_dir'),
],
// コピー先ファイルが存在する場所
'dest' => [
'driver' => 'local',
'root' => storage_path('dest_dir'),
],
ファイルのコピー(方法1)
下記のコードで異なるdisk間のファイルをコピーできます。
$srcFileName = 'srcfile.txt';
$destFileName = 'destfile.txt';
Storage::disk('dest')->put($destFileName, Storage::disk('src')->get($srcFileName));
同名のファイルがある場合は上書きされます。また、get()の処理でファイルの中身を一度全部メモリに展開するため、コピーしたいファイルが大きい場合はメモリ不足になる可能性があります。
また、コピー元またはコピー先のどちらかがdefaultのストレージの場合はdiskの記載を省略できます
// defalutからコピー
Storage::disk('dest')->put($destFileName, Storage::get($srcFileName));
// defalutへコピー
Storage::put($destFileName, Storage::disk('src')->get($srcFileName));
ファイルのコピー(方法2)
PHPスクリプトでのメモリ消費を抑えたい場合は、下記のコードにします。
Storage::disk('dest')->writeStream($destFileName, Storage::disk('src')::readStream($srcFileName));
ただし、この方法でコピーする場合、コピー先ファイルが既に存在しているとFileExistsExceptionが発生します。このため、要件によってはファイルが存在していないことを事前チェックしたり例外ハンドリングなどの処理が必要になるかもしれません。
こちらもおススメ