在 Laravel 中开始使用 Amazon S3 存储
我过去曾参与过几个使用亚马逊 S3 服务存储 Laravel 应用程序图片和文件的项目。尽管这些功能基本上已经内置在框架中,但上手过程可能会有些不适应,尤其是对于那些对 AWS 套件没有太多经验的人来说。
然而,使用 S3 的好处可能非常多,因此我认为值得整理出这个简短的教程,介绍如何开始将新的(或现有的) Laravel 应用程序的存储绑定到 Amazon S3 存储桶。
不想继续阅读?那就观看视频吧!
创建我们的项目
为了展示存储功能,我将在 Laravel 中构建一个超级基本的图像上传器。
首先,我们需要三个路由。打开你的routes/web.php
文件,创建两个 GET 请求和一个 POST 请求。它们分别用于初始登陆页面、存储图片和显示单张上传的图片。ImageController.php
为了简单起见,这三个路由都使用同一个控制器 。
以下是我对此的看法:
Route::get('/', 'ImageController@create');
Route::post('/', 'ImageController@store');
Route::get('/{image}', 'ImageController@show');
然后,在项目根目录的控制台中,我们可以使用 artisan 创建该控制器。此外,我们还可以使用带有标志的 make:model 生成包含迁移的模型--migration
。让我们看看效果如何。
php artisan make:controller ImageController
php artisan make:model Image --migration
对于这个演示应用,我们不需要数据库表中有大量的图片列。我认为文件名和 URL 就足够了。
在目录中打开新的迁移database/migrations/
,让我们修改它,使其看起来像下面这样:
public function up()
{
Schema::create('images', function(Blueprint $table) {
$table->bigIncrements('id');
$table->string('filename');
$table->string('url');
$table->timestamps();
});
}
如果我们回顾我们的routes/web.php
文件,我们会发现我们将需要ImageController 中的三种方法:create()、store() 和 update()。
创建很简单,我们实际上只想返回一个显示图片上传表单的视图,以便我们可以添加图片并点击按钮提交表单。存储需要一个请求参数,以便我们可以在表单提交后提取图片数据,并将其存储在 S3 存储桶中。最后,更新可以包含一个 Image 参数,以便我们可以在返回时进行类型提示,并将存储的图片直接流式传输到用户的浏览器中。
让我们从表单开始。使用 TailwindCSS 和一个resources/views/images/create.blade.php
文件,我制作了一个可能是我能想到的最基本的上传表单。
这个标记同样简单,它是一种发布到根页面的表单,我们在该页面创建了将数据发送到ImageController@store
方法的路由。
<div class="max-w-sm mx-auto py-8">
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="image" id="image">
<button type="submit">Upload</button>
</form>
</div>
本地保存图像
与大多数其他功能一样,Laravel 使得在文件上传后抓取并本地存储变得异常简单。在store()
ImageController 的方法中,我们可以调用 $request 对象的 file 方法,并传入文件名称作为输入(image
)。
链接到该方法我们可以使用存储方法并指定本地路径,它将自动将图像文件(具有随机生成的名称和正确的扩展名)保存到我们的本地磁盘。
这一切都包含在一行超级简单的代码中:
$path = $request->file('image')->store('images');
现在让我们将该路径返回到浏览器。
如果我们随后返回到网络浏览器中的表单,选择要上传的图像,然后单击“上传”按钮,我们将看到存储图像的相对文件路径。
浏览我们的 Laravel 应用程序storage/app
目录,我们可以看到/images
创建了一个新目录,并且我们的图像位于其中。
太棒了!它在本地运行正常!现在是时候将此功能迁移到 Amazon 了。正如我之前提到的,Laravel 已经开箱即用地处理了大部分工作。我们唯一需要做的就是在应用程序.env
文件中添加 4 个不同的值:
- AWS访问密钥ID
- AWS 秘密访问密钥
- AWS_DEFAULT_REGION
- AWS_BUCKET
让我们看看如何获得它们。
设置 S3 存储桶
前往aws.amazon.com并创建一个帐户(或使用现有帐户登录)。登录后,查看顶部菜单栏并找到“服务”项。点击该项后,会打开一个包含亚马逊大量 AWS 服务列表的窗口。向下滚动,在“存储”部分下,选择“S3”。
在以下屏幕上,您将看到已创建的所有 S3 存储桶列表,以及一个蓝色的“创建存储桶”按钮。点击它!在接下来的页面上,输入您的存储桶名称(该名称必须在整个 AWS 平台上唯一),并选择最适合您的存储桶的区域。
其余页面应保留默认值,并继续单击下一步按钮,直到成功创建存储桶。
好了,我们有了存储桶,但现在我们需要凭证才能通过编程方式访问它。再次点击“服务”菜单项,搜索“IAM”。它代表身份和访问权限管理,我们将在这里为新创建的存储桶创建 ID/密钥对。
在此屏幕左侧,点击访问管理组下的“用户”项。在下一页上,点击蓝色的“添加用户”按钮。
为您的用户填写一个用户名,并选中“Programmatic access”旁边的框,这会让 AWS 知道我们想要为该用户生成一个密钥 ID 和秘密访问密钥。
下一页可能是本教程中最令人困惑的部分,但说实话,它其实很简单。Amazon 允许您按用户确定权限,如果您需要管理大量用户,还可以将用户关联到组中。
对于我们的简单演示(说实话,对于我的大多数项目来说也是如此),我更喜欢转到“直接附加现有策略”部分,搜索,然后选中AmazonS3FullAccessS3
旁边的框。这可确保我们的用户(附加了 ID/密钥)对我们的 S3 存储桶具有完全的读/写访问权限。
单击接下来的几个屏幕,保持所有内容不变,您的用户将被成功创建!
您将进入一个包含您创建的用户及其访问密钥 ID 和秘密访问密钥的屏幕。将这两个值复制到应用程序.env
文件中,并位于上面列出的相应标题下。
文件中需要的另外两项.env
可以直接从存储桶中提取。即您创建存储桶时使用的名称,以及您在同一步骤中选择的区域。
现在,我们只需要告诉 Laravel 使用 S3 而不是本地磁盘。
将 S3 连接到我们的应用程序
回到store()
ImageController 的方法中,我们要做的就是对存储文件的一行代码进行一处修改。在store()
“images”之后的方法中,添加一个逗号和字符串“s3”:
$path = $request->file('image')->store('images', 's3');
这告诉 Laravel 您想要使用 S3 磁盘服务,该服务已在我们的应用程序的服务配置中提供。
连接的最后一步是安装 Laravel 用来作为应用程序和 S3 bucket 之间桥梁的软件包。你可以在应用程序的根目录中使用以下代码来执行此操作:
composer require league/flysystem-aws-s3-v3
好的,现在让我们回到我们的应用程序,并尝试上传文件。
成功了!返回了路径,但查看storage/app/images
目录却没有任何新内容。这是因为它被发送到了我们的 S3 存储桶。刷新存储桶后,现在出现了一个名为 images 的文件夹,点击进去就能看到我们上传的图片了!
让我们使用之前创建的模型。
将图像保存到数据库
回到store()
ImageController 中的方法,存储图片后创建一个新的图片对象。记住,我们只需要两个值:文件名和 URL。文件名可以通过basename
PHP 方法获取,URL 可以通过 Storage Facade 的 URL 助手获取。通过传入图片的保存路径,它就能方便地返回 Amazon S3 图片对象的完整 URL。
模型对象创建如下:
$image = Image::create([
'filename' => basename($path),
'url' => Storage::disk('s3')->url($path)
]);
现在我们不再像以前那样返回 $path,而是返回整个 $image 对象。
让我们回到应用的上传表单,选择一张图片,然后点击“上传”。这次,我们返回了一些 JSON 数据,其中包含图片模型的 ID、文件名和 URL。
默认情况下,该图片 URL 目前也处于私密锁定状态。如果您点击它,AWS 会返回“访问被拒绝”错误,您将无法直接查看图片。因此,我们必须另寻他法。
回到 ImageController,我们有一个show()
方法,接收图像 ID。我们可以使用类型提示的 Image 对象,并且再次感谢 Storage Facade,我们既可以从 S3 检索图像,也可以使用适当的内容类型将其作为浏览器响应进行流式传输。所有这些只需一行代码即可完成:
return Storage::disk('s3')->response('images/' . $image->filename);
如果我们使用刚刚返回的图像 ID 转到应用程序上的路径,Laravel 将从我们的 S3 存储桶中检索图像,并将其直接显示在浏览器中。
就这样
目前就这些!
您已成功学会如何:
- 上传图片文件并存储于本地
- 设置 Amazon S3 存储桶并分配凭证
- 将本地磁盘存储转换为使用 Amazon S3 存储桶
- 使用 Laravel 从 S3 存储桶中检索图像
如果您想了解有关 Laravel 开发、Amazon AWS 或其他常规 Web 开发主题的更多信息,请随时在我的YouTube 频道或Twitter上关注我。
如果您有任何疑问,请随时联系我们!
文章来源:https://dev.to/aschmelyun/getting-started-with-amazon-s3-storage-in-laravel-5b6d