Laravel League/Flysystem Getting File Url with Aws S3

Laravel league/flysystem getting file URL with AWS S3

I'm not sure what the correct way of doing this is with Flysystem, but the underlying S3Client object has a method for doing that. You could do $filesystem->getAdapter()->getClient()->getObjectUrl($bucket, $key);. Of course, building the URL is as trivial as you described, so you don't really need a special method to do it.

league/flysystem-aws-s3-v3 get custom metada

to use the S3 FlySystem adapter you need to init the S3 client

$client = new Aws\S3\S3Client($options);

In S3 SDK you could use

$allFiles = $filesystem->listContents($path)->sortByPath()->toArray();

$file = $allFiles[0];
$headers = $client->headObject(array(
"Bucket" => $bucket,
"Key" => $file->path()
));

print_r($headers->toArray());

to get the list of all file's metadata!

Get file's signed URL from amazon s3 using Filesystem Laravel 5.2

In Laravel,

$s3 = \Storage::disk('s3');
$client = $s3->getDriver()->getAdapter()->getClient();
$expiry = "+10 minutes";

$command = $client->getCommand('GetObject', [
'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
'Key' => "file/in/s3/bucket"
]);

$request = $client->createPresignedRequest($command, $expiry);

return (string) $request->getUri();

Make sure you have the AWS for flysystem composer package too (version will vary):

"league/flysystem-aws-s3-v3": "1.0.9"

How to retrieve image's name to store in image table after uploading on AWS S3 using Laravel?

Need to use ltrim(string,charlist)

$image = $request->file('image');
$data['image_name'] = time().'.'.$image->getClientOriginalExtension();
$data['path'] = Storage::disk('s3')->put('images', $request->image);
$data['ab'] = Storage::disk('s3')->url($data['path']);
$image = ltrim($data['path'],"images/");
return $image;

The $image have what you need.

Get S3Client from storage facade in Laravel 9

This was discussed in this Flysystem AWS adapter github issue:

https://github.com/thephpleague/flysystem-aws-s3-v3/issues/284

A method is being added in Laravel, and will be released next Tuesday (February 22, 2022):

https://github.com/laravel/framework/pull/41079

Workaround

The Laravel FilesystemAdapter base class is macroable, which means you could do this in your AppServiceProvider:

Illuminate\Filesystem\AwsS3V3Adapter::macro('getClient', fn() => $this->client);

Now you can call...

Storage::disk('s3')->getClient();

... and you will have an instance of the S3Client. (I love macros!)

You can remove this macro once next Tuesday's release is available.

Laravel can't connect to AWS S3

I finally found the reason why the connection didn't work.
This is how the .env file looked like:

//some env vars here...

AWS_ACCESS_KEY_ID=XXXX
AWS_SECRET_ACCESS_KEY=YYYY
AWS_DEFAULT_REGION=us-west-3
AWS_BUCKET=my-bucket
AWS_USE_PATH_STYLE_ENDPOINT=false
FILESYSTEM_DRIVER=s3

//many other env vars here...

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=

It turns out that Laravel (or maybe it was Flysystem?) already configured the same S3 variables and left the values empty. So my environment variables were getting overridden by these empty ones, leaving the connection to fail.
I guess the lesson to learn here is to always check your entire .env file if it contains multiple vars with the same key.

Bonus

After setting up S3 with Laravel, you could use these snippets to:

  • Generate a random string as new name for your image file:
$imageName = preg_replace('/[\W]/', '', base64_encode(random_bytes(18)));
  • Save an image to your S3 bucket:
Storage::disk('s3')->put($newImagePath, file_get_contents($imageName));
//$imageName is just a string containing the name of the image file and it's extension, something like 'exampleImage.png'
//make sure to include the extension of the image in the $imageName, to do that, concatenate your the name of your image with "." + $Image->extension()
  • Get an image from your S3 bucket:
$image =  Storage::disk('s3')->temporaryUrl($imagePath, Carbon::now()->addSeconds(40));   //tip: if you get a squiggly line on tempraryUrl(), it's just Intelephense shenanigans, you can just ignore it or remove it using https://github.com/barryvdh/laravel-ide-helper 
//This will generate a temporary link that your Blade file can use to access an image, this link will last for 40 seconds, this 40 seconds is the period when the image link will be accessible.
//Of course after your image loads onto the browser, even if the image link is gone, the image will remain on the page, reloading the page generates a new image link that works for another 40 seconds.
//This will work even with S3 images stored with Private visibility.

//In your blade file:
<img src="{{$image}}">
  • Check if an image exists in your S3 bucket:
if (Storage::disk('s3')->exists($imagePath)) {  //make sure to include the full path to the image file in $imagePath
//do stuff
}
  • Delete an image from your S3 bucket:
Storage::disk('s3')->delete($imagePath);

Unable to upload file in s3 bucket using laravel 5.7- Argument 1 passed to League\Flysystem\AwsS3v3\AwsS3Adapter:

After struggling for more than 4 days, I removed both
"aws/aws-sdk-php": "3.0", and "league/flysystem-aws-s3-v3": "~1.0", "league/flysystem-cached-adapter": "1.0", from composer.json and run composer require league/flysystem-aws-s3-v3

After that, it worked :)

league/flysystem-aws-s3-v3 on Laravel 8 other packages require lower version

As you've found already: spatie/laravel-backup is not yet compatible with league/flysystem v2 (which is pretty new, it got released... yesterday!).

Simply require the "old" version of that AWS package through composer require league/flysystem-aws-s3-v3:"^1.0".

After all, this is not a problem of Laravel itself.



Related Topics



Leave a reply



Submit