superbalist/flysystem-google-storage
Flysystem adapter for Google Cloud Storage. Adds a Google Storage driver for League\Flysystem so Laravel and PHP apps can store, read, and manage files in GCS using the familiar Flysystem filesystem API, with simple configuration and authentication support.
Installation
composer require superbalist/flysystem-google-storage:^7.2
Ensure flysystem/flysystem is also installed (dependency).
Service Provider & Alias
Register in config/app.php:
'providers' => [
// ...
Superbalist\FlysystemGoogleStorage\FlysystemGoogleStorageServiceProvider::class,
],
'aliases' => [
// ...
'GoogleStorage' => Superbalist\FlysystemGoogleStorage\Facades\GoogleStorage::class,
],
Configuration Publish the config:
php artisan vendor:publish --provider="Superbalist\FlysystemGoogleStorage\FlysystemGoogleStorageServiceProvider"
Update .env with Google Cloud credentials:
GOOGLE_STORAGE_BUCKET=your-bucket-name
GOOGLE_STORAGE_KEY=your-service-account-key.json
GOOGLE_STORAGE_PROJECT_ID=your-project-id
First Use Case: Upload a File
use Superbalist\FlysystemGoogleStorage\Facades\GoogleStorage;
$file = GoogleStorage::put('path/to/file.txt', fopen('local-file.txt', 'r+'));
File Operations
put() with a stream or file path.
$file = GoogleStorage::put('remote/path/file.jpg', fopen('local.jpg', 'r+'));
read() or get().
$contents = GoogleStorage::read('remote/path/file.jpg');
GoogleStorage::get('remote/path/file.jpg', 'local-copy.jpg');
delete().
GoogleStorage::delete('remote/path/file.jpg');
Directory Handling
mkdir().
GoogleStorage::mkdir('remote/folder');
listContents().
$files = GoogleStorage::listContents('remote/folder', true);
Symlinks & Metadata
createSymlink().
GoogleStorage::createSymlink('target-path', 'link-path');
getMetadata()/setMetadata().
$metadata = GoogleStorage::getMetadata('remote/path/file.jpg');
GoogleStorage::setMetadata('remote/path/file.jpg', ['customKey' => 'value']);
RFC3986 Compliant URLs Generate properly encoded URLs for sharing files:
$url = GoogleStorage::url('path/to/file.jpg');
// Returns RFC3986 compliant URL (e.g., https://storage.googleapis.com/bucket/path%2Fto%2Ffile.jpg)
Temporary (Signed) URLs Generate time-limited URLs for secure access:
$signedUrl = GoogleStorage::temporaryUrl('path/to/file.jpg', now()->addHours(1));
// Returns a signed URL valid for 1 hour
Filesystem Integration
Configure filesystems.php to use the adapter:
'disks' => [
'gcs' => [
'driver' => 'google',
'bucket' => env('GOOGLE_STORAGE_BUCKET'),
'key' => env('GOOGLE_STORAGE_KEY'),
'project_id' => env('GOOGLE_STORAGE_PROJECT_ID'),
'root' => env('GOOGLE_STORAGE_ROOT', ''),
'url' => env('GOOGLE_STORAGE_URL', null), // Optional: Custom base URL
],
],
Use via Laravel’s Storage facade:
Storage::disk('gcs')->put('file.txt', 'contents');
Queueing File Uploads Offload heavy uploads to queues:
use Illuminate\Support\Facades\Queue;
use Superbalist\FlysystemGoogleStorage\Facades\GoogleStorage;
Queue::push(function () {
GoogleStorage::put('large-file.zip', fopen('local-large.zip', 'r+'));
});
Presigned URLs (Legacy) For backward compatibility, use the adapter directly:
$url = GoogleStorage::getAdapter()->getClient()->buildPresignedUrl(
'https://storage.googleapis.com/your-bucket/file.jpg',
3600 // 1 hour
);
Credentials & Permissions
storage.objects.createstorage.objects.deletestorage.objects.updatestorage.objects.listgcloud auth application-default login for local testing.Path Handling
/) matter. Use rtrim() if needed:
$path = rtrim($path, '/');
Large Files
URL Generation
url() method now returns properly encoded URLs. Avoid manual URL encoding.Deprecation Note
Enable Debugging Configure the Google client to log requests:
$client = GoogleStorage::getAdapter()->getClient();
$client->setScopes([...]);
$client->setAuthConfig(env('GOOGLE_STORAGE_KEY'));
$client->setUseBatch(true); // For batch operations
Check HTTP Errors Wrap operations in try-catch:
try {
GoogleStorage::put('file.txt', 'contents');
} catch (\Google\Cloud\Storage\StorageException $e) {
\Log::error('Google Storage Error: ' . $e->getMessage());
}
Verify Bucket Exists Ensure the bucket exists before operations:
$buckets = GoogleStorage::getAdapter()->getClient()->bucketList();
$bucketExists = false;
foreach ($buckets as $bucket) {
if ($bucket->name() === env('GOOGLE_STORAGE_BUCKET')) {
$bucketExists = true;
break;
}
}
Custom Metadata Handling Extend the adapter to add custom metadata:
$adapter = GoogleStorage::getAdapter();
$adapter->setCustomMetadata('key', 'value');
Event Listeners Listen for file operations via Laravel events:
Storage::disk('gcs')->put('file.txt', 'contents');
// Trigger custom logic after upload.
Fallback to Local Storage
Implement a fallback disk in filesystems.php:
'disks' => [
'gcs' => [
'driver' => 'google',
// ... config ...
],
'fallback' => [
'driver' => 'local',
'root' => storage_path('app/fallback'),
],
],
Use in code:
$disk = Storage::disk(env('USE_GCS') ? 'gcs' : 'fallback');
Custom URL Generation
Override the url() method for custom domains:
$adapter = GoogleStorage::getAdapter();
$adapter->setCustomDomain('cdn.yourdomain.com');
$url = GoogleStorage::url('path/to/file.jpg');
How can I help you explore Laravel packages today?