13

我在 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() 不是很浪费吗?有没有更好的解决方案?

4

6 回答 6

14

有一种方法可以复制文件而无需将文件内容加载到内存中。

您还需要导入以下内容:

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');
于 2017-09-13T03:00:24.143 回答
10

您始终可以通过执行以下操作使用文件资源来流式传输文件(建议用于大文件):

Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));

这里提出了一个替代建议。它使用 Laravel 的 Storage 门面来读取流。基本思想是这样的:

    $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);
于 2017-02-12T00:00:10.600 回答
9

你可以试试这段代码

$contents = Storage::get($file);
Storage::disk('s3')->put($newfile,$contents);

作为 Laravel 文档,这是我发现在两个磁盘之间复制数据的简单方法

于 2017-08-29T17:46:22.987 回答
5

Laravel 现在有了允许文件流的方法putFile 。putFileAs

自动串流

如果您希望 Laravel 自动管理将给定文件流式传输到您的存储位置,您可以使用 putFile 或 putFileAs 方法。此方法接受 Illuminate\Http\File 或 Illuminate\Http\UploadedFile 实例,并将自动将文件流式传输到您想要的位置:

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');

文档链接:https ://laravel.com/docs/5.8/filesystem (自动流式传输)

希望能帮助到你

于 2020-01-21T15:17:40.333 回答
2

查看文档的唯一方法是使用put需要文件内容的方法。没有在 2 个文件系统之间复制文件的方法,因此您提供的解决方案可能是目前唯一的一个。

如果你仔细想想,最后当从本地文件系统复制文件到s3时,你需要有文件内容才能把它放到s3中,所以在我看来确实没有那么浪费。

于 2015-04-09T04:59:34.177 回答
0

我通过以下方式解决了它:

$contents = \File::get($destination);
\Storage::disk('s3')
    ->put($s3Destination,$contents);

有时我们没有使用$contents = Storage::get($file);- storage 函数获取数据,因此我们必须使用 Laravel File提供数据的根路径,而不是使用Storage的存储路径。

于 2019-08-06T11:32:18.830 回答