在 Laravel 中开始使用 Amazon S3 存储

2025-06-04

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


Enter fullscreen mode Exit fullscreen mode

然后,在项目根目录的控制台中,我们可以使用 artisan 创建该控制器。此外,我们还可以使用带有标志的 make:model 生成包含迁移的模型--migration。让我们看看效果如何。



php artisan make:controller ImageController
php artisan make:model Image --migration


Enter fullscreen mode Exit fullscreen mode

对于这个演示应用,我们不需要数据库表中有大量的图片列。我认为文件名和 URL 就足够了。

在目录中打开新的迁移database/migrations/,让我们修改它,使其看起来像下面这样:



public function up()
{
    Schema::create('images', function(Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('filename');
        $table->string('url');
        $table->timestamps();
    });
}


Enter fullscreen mode Exit fullscreen mode

如果我们回顾我们的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>


Enter fullscreen mode Exit fullscreen mode

本地保存图像

与大多数其他功能一样,Laravel 使得在文件上传后抓取并本地存储变得异常简单。在store()ImageController 的方法中,我们可以调用 $request 对象的 file 方法,并传入文件名称作为输入(image)。

链接到该方法我们可以使用存储方法并指定本地路径,它将自动将图像文件(具有随机生成的名称和正确的扩展名)保存到我们的本地磁盘。

这一切都包含在一行超级简单的代码中:



$path = $request->file('image')->store('images');


Enter fullscreen mode Exit fullscreen mode

现在让我们将该路径返回到浏览器。

如果我们随后返回到网络浏览器中的表单,选择要上传的图像,然后单击“上传”按钮,我们将看到存储图像的相对文件路径。

浏览我们的 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 和秘密访问密钥。

AWS IAM 用户详细信息页面的屏幕截图

下一页可能是本教程中最令人困惑的部分,但说实话,它其实很简单。Amazon 允许您按用户确定权限,如果您需要管理大量用户,还可以将用户关联到组中。

对于我们的简单演示(说实话,对于我的大多数项目来说也是如此),我更喜欢转到“直接附加现有策略”部分,搜索,然后选中AmazonS3FullAccessS3旁边的框。这可确保我们的用户(附加了 ID/密钥)对我们的 S3 存储桶具有完全的读/写访问权限。

单击接下来的几个屏幕,保持所有内容不变,您的用户将被成功创建!

您将进入一个包含您创建的用户及其访问密钥 ID 和秘密访问密钥的屏幕。将这两个值复制到应用程序.env文件中,并位于上面列出的相应标题下。

文件中需要的另外两项.env可以直接从存储桶中提取。即您创建存储桶时使用的名称,以及您在同一步骤中选择的区域。

现在,我们只需要告诉 Laravel 使用 S3 而不是本地磁盘。

将 S3 连接到我们的应用程序

回到store()ImageController 的方法中,我们要做的就是对存储文件的一行代码进行一处修改。在store()“images”之后的方法中,添加一个逗号和字符串“s3”:



$path = $request->file('image')->store('images', 's3');


Enter fullscreen mode Exit fullscreen mode

这告诉 Laravel 您想要使用 S3 磁盘服务,该服务已在我们的应用程序的服务配置中提供。

连接的最后一步是安装 Laravel 用来作为应用程序和 S3 bucket 之间桥梁的软件包。你可以在应用程序的根目录中使用以下代码来执行此操作:



composer require league/flysystem-aws-s3-v3


Enter fullscreen mode Exit fullscreen mode

好的,现在让我们回到我们的应用程序,并尝试上传文件。

成功了!返回了路径,但查看storage/app/images目录却没有任何新内容。这是因为它被发送到了我们的 S3 存储桶。刷新存储桶后,现在出现了一个名为 images 的文件夹,点击进去就能看到我们上传的图片了!

让我们使用之前创建的模型。

将图像保存到数据库

回到store()ImageController 中的方法,存储图片后创建一个新的图片对象。记住,我们只需要两个值:文件名和 URL。文件名可以通过basenamePHP 方法获取,URL 可以通过 Storage Facade 的 URL 助手获取。通过传入图片的保存路径,它就能方便地返回 Amazon S3 图片对象的完整 URL。

模型对象创建如下:



$image = Image::create([
    'filename' => basename($path),
    'url' => Storage::disk('s3')->url($path)
]);


Enter fullscreen mode Exit fullscreen mode

现在我们不再像以前那样返回 $path,而是返回整个 $image 对象。

让我们回到应用的上传表单,选择一张图片,然后点击“上传”。这次,我们返回了一些 JSON 数据,其中包含图片模型的 ID、文件名和 URL。

来自我们的 Laravel 应用程序的 JSON 图像对象的屏幕截图

默认情况下,该图片 URL 目前也处于私密锁定状态。如果您点击它,AWS 会返回“访问被拒绝”错误,您将无法直接查看图片。因此,我们必须另寻他法。

回到 ImageController,我们有一个show()方法,接收图像 ID。我们可以使用类型提示的 Image 对象,并且再次感谢 Storage Facade,我们既可以从 S3 检索图像,也可以使用适当的内容类型将其作为浏览器响应进行流式传输。所有这些只需一行代码即可完成:



return Storage::disk('s3')->response('images/' . $image->filename);


Enter fullscreen mode Exit fullscreen mode

如果我们使用刚刚返回的图像 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
PREV
100+ 面向 Web 开发人员的项目创意资源
NEXT
仅用三行 JavaScript 代码即可实现文本转语音