Uploading Files to S3 or a Similar Server in Laravel
Published: 2023-07-02 06:00:45

**Introduction**
Uploading files to cloud storage services like Amazon S3 is a common requirement for many Laravel applications. In this article, we'll explore how to upload files to an S3 bucket using Laravel and the AWS SDK for PHP. We'll also cover generating pre-signed URLs for accessing the uploaded files.

**Prerequisites**
Before we begin, make sure you have the following prerequisites in place:

1-Laravel installed on your system.
2-AWS account with S3 bucket credentials.
3-AWS SDK for PHP installed.


**Step 1: Set Up the AWS SDK for PHP**
To get started, install the AWS SDK for PHP in your Laravel project. Use Composer to install the SDK by running the following command in your project root directory:

```
composer require aws/aws-sdk-php
```
**Step 2: Configure Laravel Environment Variables**
Next, open your Laravel project's .env file and add the following environment variables
and if you have endpoint also add it:

```
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your-s3-bucket-name
AWS_ENDPOINT=your-s3-endpoint (e.g., https://s3.your-region.amazonaws.com)
AWS_USE_PATH_STYLE_ENDPOINT=false
```

**Step 3: Implement the File Upload Functionality**
In your Laravel application, create a new controller or use an existing one. Let's assume you have a controller called S3Controller. Inside the controller, add the following code:

```
<?php

namespace App\Http\Controllers;

use Aws\S3\S3Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class S3Controller extends Controller
{
    public function uploadFile(Request $request)
    {
        $file = $request->file('my_file');
        $bucket = env('AWS_BUCKET');
        $expiry = '+5 minutes'; // Expiration time for the URL

        $path = Storage::disk('s3')->put('folder-name', $file);

        // Set the visibility of the uploaded file to public
        Storage::disk('s3')->setVisibility($path, 'public');


        // Generate a pre-signed URL for the uploaded file
       $s3Client = new S3Client([
            'credentials' => [
                'key' => env('AWS_ACCESS_KEY_ID'),
                'secret' => env('AWS_SECRET_ACCESS_KEY'),
            ],
            'region' => 'us-east-1',
            'version' => 'latest',
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => 
            env('AWS_USE_PATH_STYLE_ENDPOINT'),
        ]);

        $command = $s3Client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key' => $path,
        ]);


        $signedUrl = $s3Client
           ->createPresignedRequest($command, $expiry)
           ->getUri();

        return $signedUrl;
    }


// the function for get the file after upload

    public function get(Request $request)
    {

    // Specify the key and bucket name of the S3 object

   // $key must be like that get from request or database   
  //$key='foldernameA6Hlt7uyoZUpqsfIpeEpT7YRgKJ9JLGRMfnXuyRw.jpg';
      
        $key= $request->file('my_file');
        $bucket = env('AWS_BUCKET');
        $expiry = '1 minutes'; // Expiration time for the URL

        // Instantiate the S3 client
        $s3Client = new S3Client([
            'credentials' => [
                'key' => env('AWS_ACCESS_KEY_ID'),
                'secret' => env('AWS_SECRET_ACCESS_KEY'),
            ],
            'region' => 'us-east-1',
            'version' => 'latest',
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => 
            env('AWS_USE_PATH_STYLE_ENDPOINT'),
        ]);
        $command = $s3Client->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key' => $key,
        ]);
        $signedUrl = $s3Client
        ->createPresignedRequest($command, $expiry)
        ->getUri();

        return $signedUrl;


    }
}

```



**Explanation:**

- The uploadFile method handles the file upload functionality.

- It retrieves the uploaded file from the request and stores it in 
  the specified S3 bucket under the "folder-name" directory.

- The visibility of the uploaded file is set to public, allowing 
  public access.

- The $url variable contains the full URL of the uploaded file.

- The $signedUrl variable contains a pre-signed URL for accessing 
  the uploaded file, valid for a specific duration.

- The get method retrieves the pre-signed URL for a specific file stored in the S3 bucket. It specifies the key and bucket name of the S3 object and generates a pre-signed URL using the AWS SDK.

 


**Conclusion:**

In this article, we learned how to upload files to an S3 bucket in Laravel using the AWS SDK for PHP. We also explored how to generate pre-signed URLs for accessing the uploaded files. By following the steps outlined in this article, you can easily integrate file upload functionality with S3 or a similar server in your Laravel applications.