Do you want to upload files from your local system to the AWS S3 bucket using Laravel?
If yes then read this article completely. In this article I will show you how easily you can upload files from your local system to AWS S3 bucket. So let's get started.
I have created a class by the name of "AwsS3Storage.php". In this class, you will see I have created a function pushMedia(). It accepted an array as a parameter with 'sourcePath' and 'targetPath'. SourcePath is from where you want to upload files and targetPath is the path of your AWS S3 bucket where you want to store files.
In my case, I need to upload the files from my storage/projects folder to AWS so I called the function like below. You can change it as per your requirement -
$provider = new AwsS3Storage ();$targetPath = "projects/{$this->projectId}/media/{$this->mediaId}/";$sourcePath = storage_path("app/{$targetPath}/");/** Upload all project media on AWS server. */ $uploadMedia = $provider->pushMedia([ 'sourcePath' => $sourcePath, 'targetPath' => $targetPath ]);
Below is the AwsS3Storage.php class file:<?php
namespace App\Http\Controllers\Api\v1\UploadProviders;
use App\Exceptions\MultipartUploadException;use App\Exceptions\CustomException;use Aws\Exception\AwsException;use Aws\S3\MultipartUploader;use Aws\S3\S3Client;use Aws\S3\S3ClientInterface;
class AwsS3Storage{ private $s3Client;
public function __construct() { $this->s3Client = new S3Client([ 'credentials' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), ], 'region' => env('AWS_DEFAULT_REGION'), 'version' => 'latest', ]); } /** * Accept sourcePath and targetPath files path. * sourcePath => where all local files stored. * targetPath => where the files will save on AWS. */ public function pushMedia($params) { try { $this->scanDirectory($params); } catch (MultipartUploadException $e) { $params = $e->getState()->getId(); $this->s3Client->abortMultipartUpload($params); throw new CustomException($e); } catch (Exception $e) { throw $e; }
return [ "success" => true, "messsage" => "File uploaded successfully", ]; }
/** * Scaned all the directories and * Loop through array of all files. */ public function scanDirectory($params) { $sourcePath = array_diff(scandir($params['sourcePath']), ['.', '..']); if (count($sourcePath)>0) { foreach($sourcePath as $fileName) { $params['fileName'] = $fileName; $this->uploadFile($params); } } else { throw new MultipartUploadException("There are no file in directory."); } }
/** * Upload files on AWS server in chunk. */ public function uploadFile($params) { $source = $params['sourcePath'] . $params['fileName']; $target = $params['targetPath'] . $params['fileName']; $uploader = new MultipartUploader($this->s3Client, $source, [ 'bucket' => env('AWS_BUCKET'), 'key' => $target, 'part_size' => 5*1024*1024 ]); $uploader->upload(); }
/** * Return AWS file signed path * Accept two parameters. Bucket file path. * Time to availabe signed link. */ public function awsFilePath($path, $duration = 5) { $command = $this->s3Client->getCommand('GetObject', [ 'Bucket' => env('AWS_BUCKET'), 'Key' => ltrim($path, "/") ]); $request = $this->s3Client->createPresignedRequest($command, "+{$duration} minutes"); $file = (string)$request->getUri(); return $file; }}
Happy Coding...