Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel5:如何将本地文件复制到AmazonS3?_Laravel_Amazon S3_Upload_Laravel 5_Laravel Filesystem - Fatal编程技术网

Laravel5:如何将本地文件复制到AmazonS3?

Laravel5:如何将本地文件复制到AmazonS3?,laravel,amazon-s3,upload,laravel-5,laravel-filesystem,Laravel,Amazon S3,Upload,Laravel 5,Laravel Filesystem,我正在用Laravel5编写代码来定期备份MySQL数据库。到目前为止,我的代码如下所示: $filename = 'database_backup_'.date('G_a_m_d_y').'.sql'; $destination = storage_path() . '/backups/'; $database = \Config::get('database.connections.mysql.database'); $username = \Config:

我正在用Laravel5编写代码来定期备份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?
    // ????????????????????????????????
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
    $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);
我在网上看到过一些建议我采取以下措施的解决方案:

$disk->put('my/bucket/' . $filename, file_get_contents($destination . $filename));

但是,对于大型文件,使用file_get_contents()不是很浪费吗?有更好的解决方案吗?

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


如果您仔细考虑一下,最后在将文件从本地文件系统复制到s3时,您需要有文件内容才能将其放入s3中,因此在我看来,确实没有那么浪费。

您可以通过以下操作始终使用文件资源来流式传输文件(对于大文件更可取):

    $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?
    // ????????????????????????????????
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
    $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);
另一个建议是。它使用Laravel的存储外观来读取流。基本思想如下:

    $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?
    // ????????????????????????????????
Storage::disk('s3')->put('my/bucket/' . $filename, fopen('path/to/local/file', 'r+'));
    $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文档,这是我发现的在两个磁盘之间复制数据的简单方法。有一种方法可以复制文件,而无需将文件内容加载到内存中

您还需要导入以下内容:

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)获取数据
-存储函数,因此我们必须使用LaravelFile给出数据的根路径,而不是使用storage

给出存储路径。Laravel现在有
putFile
putFileAs
方法来允许文件流

自动流媒体

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

链接到文档:(自动流媒体)


希望能有所帮助

谢谢Marcin。我觉得这可能是浪费,因为file_get_内容会在发送到S3之前将整个文件拉入内存。我希望有一个解决方案,该文件将从本地文件流式传输到S3。如果您的文件只有1或2兆,这并不是什么大问题,但我可以看到较大文件的内存不足。所有这些都是我的猜测,所以请恕我直言。我相信有一种方法可以通过Laravel 5上的Flysystem使用streams来实现这一点。也许值得向弗兰克·德容格(Frank de Jonge)请教如何做到这一点(Flysystem的作者)。基本上,您通过流打开一个文件,将内容拉入,同时将该内容推送到S3上的文件中。这样就不必将整个文件加载到内存中,这在很多方面都很好。@MarcinNabiałek我不是有意侮辱你,如果这是不礼貌的行为,我向你道歉。我更新了“已接受的答案”,以便看到此帖子的开发人员关注itod的答案,这可能是目前最好的方法。@clone45是的,我理解,但在询问时,可能还没有Laravel 5.8,这种方法不起作用。如果在Laravel 15中,它将被更改,并且有人回答,那么您将再次将已接受的答案更改为这个?@MarcinNabiałek如果您想讨论这个问题,请随时通过我的clone45 gmail地址给我发电子邮件。我在网上看到了双方的争论。这是一个很好的问题,也是我现在的目标。现在我将研究(这看起来很有希望)以及下面来自@user4603841的建议。你能找到解决办法吗