laravel-file-s3-like maintained by andreinocenti
Laravel Package - Files to S3 Like Cloud Storage
This is a Laravel package that handles and make easy the upload, overwrite, delete, cdn purge of files and directories on AWS S3 like cloud storages.
It supports sending a file URL, a form uploaded file (UploadedFile) or a base64 file string.
It supports generating a presigned url.
Support
Currently supports:
- Digital Ocean SPACES
- Google Cloud Storage (GCS)
Configuration
You should install it via composer:
composer require andreinocenti/laravel-file-s3-like
1. Digital Ocean Spaces
This package use the Laravel Illuminate\Support\Facades\Storage facade to handle the files.
So you must config the filesystem AWS like disk that you want to use.
Below the optimal config to be used in config/filesystem.php:
'spaces-disk' => [
'driver' => 's3',
'key' => env('SPACES_ACCESS_KEY_ID'),
'secret' => env('SPACES_SECRET_ACCESS_KEY'),
'region' => env('SPACES_DEFAULT_REGION'),
'bucket' => env('SPACES_BUCKET'),
'url' => env('SPACES_URL'),
'endpoint' => env('SPACES_ENDPOINT'),
'folder' => env('SPACES_FOLDER'), // This will be the default directory used. It can be empty, if so the default directory will be the bucket root
'cdn_endpoint' => env('SPACES_CDN_ENDPOINT'), // at Digital Ocean Spaces the CDN is auto set when a file is uploaded. So set here the cdn_endpoint (edge)
'use_path_style_endpoint' => env('SPACES_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
2. Google Cloud Storage (GCS)
To use GCS, you need to install the required dependencies:
composer require google/cloud-storage spatie/laravel-google-cloud-storage
To see more GCS filesystem configs check: https://github.com/spatie/laravel-google-cloud-storage
For uniform bucket level access use: 'visibility_handler' => \League\Flysystem\GoogleCloudStorage\UniformBucketLevelAccessVisibility::class
Then configure the disk in config/filesystem.php:
'gcs' => [
'driver' => 'gcs',
'project_id' => env('GOOGLE_CLOUD_PROJECT_ID', 'your-project-id'),
'key_file_path' => env('GOOGLE_APPLICATION_CREDENTIALS'), // Path to service account json file
'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET', 'your-bucket'),
'path_prefix' => env('GOOGLE_CLOUD_STORAGE_PATH_PREFIX', null), // Optional: prefix for all files
'storage_api_uri' => env('GOOGLE_CLOUD_STORAGE_API_URI', null), // Optional: custom API URI
'api_endpoint' => env('GOOGLE_CLOUD_STORAGE_API_ENDPOINT', null), // Optional: custom API endpoint
'visibility_handler' => \League\Flysystem\GoogleCloudStorage\UniformBucketLevelAccessVisibility::class, // for uniform bucket level access
'throw' => false,
],
Ensure you have your Google Cloud Service Account JSON key file reachable and the path correctly set in GOOGLE_APPLICATION_CREDENTIALS environment variable.
Usage
Digital Ocean Spaces
You can use the FileS3LikeSpaces facade:
use AndreInocenti\LaravelFileS3Like\Facades\FileS3LikeSpaces;
FileS3LikeSpaces::disk('spaces-disk')
->directory('images')
->upload($file, 'new-test');
Or using the generic FileS3Like facade:
use AndreInocenti\LaravelFileS3Like\Facades\FileS3Like;
FileS3Like::repository('spaces')
->disk('spaces-disk')
->directory('images')
->upload($file, 'new-test');
Google Cloud Storage (GCS)
Use the FileS3Like facade with the gcs repository:
use AndreInocenti\LaravelFileS3Like\Facades\FileS3Like;
FileS3Like::repository('gcs')
->disk('gcs') // The disk name configured in config/filesystems.php
->directory('uploads')
->upload($file, 'profile-picture');
Upload from stream
Use uploadStream when you already have an open readable stream and want to avoid loading the full file into memory.
use AndreInocenti\LaravelFileS3Like\Facades\FileS3Like;
$stream = fopen(storage_path('app/large-video.mp4'), 'r');
$diskFile = FileS3Like::repository('spaces') // or 'gcs'
->disk('spaces')
->directory('videos')
->uploadStream($stream, 'large-video.mp4', 'video/mp4');
fclose($stream);
Use saveStream when you want the same semantics as save:
spaces: upload and purge CDN cachegcs: same behavior as upload
use AndreInocenti\LaravelFileS3Like\Facades\FileS3LikeSpaces;
$stream = fopen(storage_path('app/banner.png'), 'r');
$diskFile = FileS3LikeSpaces::disk('spaces-disk')
->directory('images')
->saveStream($stream, 'banner.png', 'image/png');
fclose($stream);
Methods / Accessors
FileS3Like and its repositories (Eg: FileS3LikeSpaces, FileS3LikeGCS)
Presigned URL usage
Use presignedUrl when you need a temporary URL for clients to upload directly to the bucket.
use AndreInocenti\LaravelFileS3Like\Facades\FileS3Like;
$upload = FileS3Like::repository('gcs') // or 'spaces'
->disk('gcs')
->directory('uploads')
->presignedUrl(
filepath: 'avatars', // directory inside the configured folder
filename: 'profile.png', // optional; defaults to UUID
expiration: 600, // seconds
fileType: 'image/png', // mime or extension; sets Content-Type
public: true, // optional; false keeps it private
);
return response()->json($upload);
The returned Fluent object contains the presigned URL and useful metadata:
{
"presigned_url": "https://storage.googleapis.com/...",
"key": "uploads/avatars/profile.png",
"public_url": "https://storage.googleapis.com/your-bucket/uploads/avatars/profile.png",
"expires": "2024-04-30 12:34:56",
"headers": {
"Content-Type": "image/png",
"ACL": "public-read"
},
"accepted_mime": "image/png",
"accepted_ext": "png"
}
Send the provided headers with the upload request to ensure the ACL and mime type are applied.
DiskFile
DiskFile is a DTO class that is created and delivered when the functions upload or save are called. The class contain accessors that returns some file data.