How to Upload Files to Amazon S3 in Laravel ?

Soulaimaneyh
6 min readDec 25, 2022

--

Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

Amazon S3 is a cloud object storage with industry-leading scalability, data availability, security, and performance. Amazon S3 uses the same scalable storage infrastructure that Amazon.com uses to run its e-commerce network.

To upload a file to Amazon S3 in Laravel, you will need to use the AWS SDK for PHP and the Laravel filesystem configuration.

Take a look at filesystems disk that is available which is s3 which stands for a veritably popular amazon AWS s3 service where you can store your files it’s not free so check the pricing on AWS but a lot of people use that and i use it for my own web applications.

I highly recommend it if you don’t want to store the files on the same
server as the project itself and as you can see in the configuration there are parameters that you need to provide and then when uploading the files you just provide the disk.

Where to upload to the most tricky part however is not the Laravel part in this case it’s actually setting up the s3 environment buckets and all of that so i will try to demonstrate you that in this post.

// config/filesystems.php
'disks' => [
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT')
],

],

AWS Console Part

Here is how you can do this, I’m logged in in my AWS management console in services i search for s3 i get in here and i see the list of my buckets every bucket is usually used for one project it’s kind of like a folder each bucket has its own region and its own settings and let’s create a new bucket for our own file upload

Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

And then we need to have key id and access key where do we get those from in AWS we need to search for another service called IAM stands for identity and access management, you simply have to follow the steps to create a new user for this project, after which you will get access to your keys.

Next, you will need to add your AWS credentials to your Laravel configuration. You can do this by adding the following lines to your .env file:

AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-west-1

Make sure to replace your_access_key and your_secret_key with your actual AWS access key and secret key.

Laravel Part

Then in the code where you actually store the file in this case in our case it’s file stored as avatar on registration for Laravel ui.

<form method="POST" action="{{ route('register') }}" enctype="multipart/form-data">
{{-- ... --}}
<div class="row mb-3">
<label for="avatar" class="col-md-4 col-form-label text-md-end">{{ __('Avatar') }}</label>

<div class="col-md-6">
<input id="avatar" type="file" class="form-control @error('avatar') is-invalid @enderror" name="avatar" required autocomplete="avatar">

@error('avatar')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
{{-- ... --}}
</form>
// Auth/RegisterController.php

protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,gif,svg', 'max:2048'],
]);
}

protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);

if (request()->hasFile('avatar')) {
$file = request('avatar');
$filename = $file->getClientOriginalName();

$file->storeAs('avatars/'. $user->id, $filename, 's3');

$user->avatar = $filename;
$user->save();
}

return $user;
}
  1. First, you will need to install the AWS SDK for PHP and configure your AWS credentials. You can do this by running the following command:
composer require league/flysystem-aws-s3-v3

You can select not public so it’s not that disk anymore but instead the s3 finally you need

$file->storeAs('avatars/'. $user->id, $filename, 's3');

This will store the file at the specified path in your S3 bucket and make it publicly accessible.

You can also use the putFile method to store a file from a local path:

use Illuminate\Support\Facades\Storage;

$path = 'avatars/'. $user->id .'/'. $filename;

Storage::disk('s3')->putFile($path, $path, 'public');

The putFile method will automatically read the contents of the file and upload it to S3.

You can also specify the visibility of the file by passing the 'private' or 'public' argument to the put or putFile methods.

We can now test it out:

Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

And as a result, this is what we will get:

Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

To make an Amazon S3 bucket and its contents publicly accessible, you can follow these steps:

  1. Sign in to the AWS Management Console and open the Amazon S3 console.
  2. In the left-hand navigation panel, choose the bucket that you want to make public.
  3. In the Properties tab, choose Permissions.
  4. In the Public access section, choose Edit.
  5. In the Edit Public Access Settings dialog box, choose the options that you want to allow public access for, and then choose Save.
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

Note that these steps will only allow public access to the objects within the bucket. If you want to make the bucket itself publicly accessible, you will also need to enable public access to the bucket itself. To do this, follow these steps:

  1. In the Permissions tab, choose Add bucket policy.
  2. In the Bucket Policy Editor, enter a policy that allows public access to the bucket. An example policy that allows public read access to all objects in the bucket is shown below:
  3. Choose Save.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::soulaimane-yahya-s3/*"
}
]
}

Note that making objects or a bucket publicly accessible means that anyone on the internet will be able to access and download the objects stored in the bucket. You should be careful to only allow public access to objects or buckets that you want to be publicly available.

Now we can access our avatar:

<li class="nav-item">
<img src="{{Storage::disk('s3')->url('/avatars/'. auth()->id() .'/'. auth()->user()->avatar) ?? 'https://ui-avatars.com/api/?name=' . auth()->user()->name}}" alt="user-avatar" width="40" class="img-fluid rounded-circle">
</li>
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

Other way, we can access the file using Storage response:

// web.php
Route::get('/avatars/{userId}', [HomeController::class, 'getAvatar']);

// HomeController
public function getAvatar($userId)
{
$user = User::find($userId);
return Storage::disk('s3')->response('/avatars/'. $userId .'/'. $user->avatar);
}

And as a result, this is what we will get:

Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).
Laravel PHP framework for web application development, and Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure cloud storage service provided by Amazon Web Services (AWS).

Read me about this 👇

Useful Functions of Laravel Eloquent every one should know !

Conclusion:

For more information on using the AWS SDK for PHP and the Laravel filesystem, you can refer to the AWS SDK for PHP documentation and the Laravel documentation.

If you have any idea or do you have any preferred way, let us know in the comments section below!

--

--