Laravel 5: 如何将本地文件复制到Amazon S3?
Laravel 5: How do you copy a local file to Amazon S3?
我正在 Laravel 5 中编写代码以定期备份 MySQL 数据库。到目前为止,我的代码如下所示:
$filename = 'database_backup_'.date('G_a_m_d_y').'.sql';
$destination = storage_path() . '/backups/';
$database = \Config::get('database.connections.mysql.database');
$username = \Config::get('database.connections.mysql.username');
$password = \Config::get('database.connections.mysql.password');
$sql = "mysqldump $database --password=$password --user=$username --single-transaction >$destination" . $filename;
$result = exec($sql, $output); // TODO: check $result
// Copy database dump to S3
$disk = \Storage::disk('s3');
// ????????????????????????????????
// What goes here?
// ????????????????????????????????
我在网上看到的解决方案建议我这样做:
$disk->put('my/bucket/' . $filename, file_get_contents($destination . $filename));
但是,对于大文件,使用file_get_contents()不是很浪费吗?有没有更好的解决方案?
查看文档,唯一的方法是使用需要文件内容的方法put
。没有在 2 个文件系统之间复制文件的方法,所以目前您提供的解决方案可能是唯一的。
仔细想想,最后从本地文件系统复制文件到s3时,需要有文件内容才能放到S3中,所以在我看来确实没有那么浪费。
您始终可以使用文件资源来流式传输文件(建议用于大文件),方法如下:
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
另一个建议是 proposed here。它使用 Laravel 的 Storage facade 来读取流。基本思路是这样的:
$inputStream = Storage::disk('local')->getDriver()->readStream('/path/to/file');
$destination = Storage::disk('s3')->getDriver()->getAdapter()->getPathPrefix().'/my/bucket/';
Storage::disk('s3')->getDriver()->putStream($destination, $inputStream);
你可以试试这个代码
$contents = Storage::get($file);
Storage::disk('s3')->put($newfile,$contents);
作为 Laravel 文档,这是我发现在两个磁盘之间复制数据的简单方法
有一种方法可以复制文件,而无需使用 MountManager 将文件内容加载到内存中。
您还需要导入以下内容:
use League\Flysystem\MountManager;
现在您可以像这样复制文件了:
$mountManager = new MountManager([
's3' => \Storage::disk('s3')->getDriver(),
'local' => \Storage::disk('local')->getDriver(),
]);
$mountManager->copy('s3://path/to/file.txt', 'local://path/to/output/file.txt');
我是这样解决的:
$contents = \File::get($destination);
\Storage::disk('s3')
->put($s3Destination,$contents);
有时我们无法使用 $contents = Storage::get($file);
获取数据 - 存储功能,因此我们必须使用 Laravel File 来提供数据的根路径使用 Storage.
的存储路径
Laravel 现在有 putFile
和 putFileAs
方法来允许文件流。
Automatic Streaming
If you would like Laravel to automatically manage
streaming a given file to your storage location, you may use the
putFile or putFileAs method. This method accepts either a
Illuminate\Http\File or Illuminate\Http\UploadedFile instance and will
automatically stream the file to your desired location:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));
// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
Link 到文档:https://laravel.com/docs/5.8/filesystem(自动流式传输)
希望对您有所帮助
我正在 Laravel 5 中编写代码以定期备份 MySQL 数据库。到目前为止,我的代码如下所示:
$filename = 'database_backup_'.date('G_a_m_d_y').'.sql';
$destination = storage_path() . '/backups/';
$database = \Config::get('database.connections.mysql.database');
$username = \Config::get('database.connections.mysql.username');
$password = \Config::get('database.connections.mysql.password');
$sql = "mysqldump $database --password=$password --user=$username --single-transaction >$destination" . $filename;
$result = exec($sql, $output); // TODO: check $result
// Copy database dump to S3
$disk = \Storage::disk('s3');
// ????????????????????????????????
// What goes here?
// ????????????????????????????????
我在网上看到的解决方案建议我这样做:
$disk->put('my/bucket/' . $filename, file_get_contents($destination . $filename));
但是,对于大文件,使用file_get_contents()不是很浪费吗?有没有更好的解决方案?
查看文档,唯一的方法是使用需要文件内容的方法put
。没有在 2 个文件系统之间复制文件的方法,所以目前您提供的解决方案可能是唯一的。
仔细想想,最后从本地文件系统复制文件到s3时,需要有文件内容才能放到S3中,所以在我看来确实没有那么浪费。
您始终可以使用文件资源来流式传输文件(建议用于大文件),方法如下:
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
另一个建议是 proposed here。它使用 Laravel 的 Storage facade 来读取流。基本思路是这样的:
$inputStream = Storage::disk('local')->getDriver()->readStream('/path/to/file');
$destination = Storage::disk('s3')->getDriver()->getAdapter()->getPathPrefix().'/my/bucket/';
Storage::disk('s3')->getDriver()->putStream($destination, $inputStream);
你可以试试这个代码
$contents = Storage::get($file);
Storage::disk('s3')->put($newfile,$contents);
作为 Laravel 文档,这是我发现在两个磁盘之间复制数据的简单方法
有一种方法可以复制文件,而无需使用 MountManager 将文件内容加载到内存中。
您还需要导入以下内容:
use League\Flysystem\MountManager;
现在您可以像这样复制文件了:
$mountManager = new MountManager([
's3' => \Storage::disk('s3')->getDriver(),
'local' => \Storage::disk('local')->getDriver(),
]);
$mountManager->copy('s3://path/to/file.txt', 'local://path/to/output/file.txt');
我是这样解决的:
$contents = \File::get($destination);
\Storage::disk('s3')
->put($s3Destination,$contents);
有时我们无法使用 $contents = Storage::get($file);
获取数据 - 存储功能,因此我们必须使用 Laravel File 来提供数据的根路径使用 Storage.
Laravel 现在有 putFile
和 putFileAs
方法来允许文件流。
Automatic Streaming
If you would like Laravel to automatically manage streaming a given file to your storage location, you may use the putFile or putFileAs method. This method accepts either a Illuminate\Http\File or Illuminate\Http\UploadedFile instance and will automatically stream the file to your desired location:
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));
// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
Link 到文档:https://laravel.com/docs/5.8/filesystem(自动流式传输)
希望对您有所帮助