Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Google Cloud Storage Laravel Package

league/flysystem-google-cloud-storage

Flysystem adapter for Google Cloud Storage (GCS). Install via composer to use GCS as a filesystem in Flysystem, with full support through the main Flysystem project. See official docs for configuration and usage.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require league/flysystem-google-cloud-storage
    
  2. Configure Google Cloud SDK Ensure you have:

    • A Service Account with Storage Admin or appropriate permissions.
    • A JSON key file (service-account-key.json) downloaded from Google Cloud Console.
    • The Google Cloud SDK installed and authenticated (gcloud auth application-default login for local testing).
  3. Basic Usage

    use League\Flysystem\Filesystem;
    use League\Flysystem\GoogleCloudStorage\GoogleCloudStorageAdapter;
    
    $adapter = new GoogleCloudStorageAdapter('your-bucket-name', [
        'keyFilePath' => '/path/to/service-account-key.json',
        'projectId'   => 'your-project-id',
    ]);
    
    $filesystem = new Filesystem($adapter);
    
    // Write a file
    $filesystem->write('test.txt', 'Hello, GCS!');
    
    // Read a file
    $content = $filesystem->read('test.txt');
    
  4. First Use Case Replace local file storage in Laravel’s filesystem.php config:

    'disks' => [
        'gcs' => [
            'driver' => 'google',
            'bucket' => env('GCS_BUCKET'),
            'keyFile' => env('GCS_KEY_PATH'),
            'projectId' => env('GCS_PROJECT_ID'),
        ],
    ],
    

    Then use via the facade:

    Storage::disk('gcs')->put('file.jpg', file_get_contents('local.jpg'));
    

Implementation Patterns

Workflows

  1. File Uploads with Metadata Leverage GCS’s metadata support for custom attributes:

    $adapter->write('file.jpg', file_get_contents('local.jpg'), [
        'metadata' => [
            'customKey' => 'customValue',
            'contentType' => 'image/jpeg',
        ],
    ]);
    
  2. Signed URLs for Secure Downloads Generate time-limited URLs for client-side downloads:

    $url = $adapter->getClient()->storage()->object('bucket', 'file.jpg')->signedUrl(
        new \DateTime('+1 hour'),
        ['response-disposition' => 'attachment; filename="file.jpg"']
    );
    
  3. Streaming Large Files Use streams to avoid memory issues with large files:

    $stream = fopen('local-large-file.zip', 'r');
    $filesystem->writeStream('remote-large-file.zip', $stream);
    fclose($stream);
    
  4. Lifecycle Management Automate object expiration or transitions:

    $adapter->getClient()->storage()->bucket('bucket')->update(
        ['lifecycle' => [
            'rule' => [
                'action' => ['type' => 'Delete'],
                'condition' => ['age' => 30], // Delete after 30 days
            ],
        ]]
    );
    

Integration Tips

  • Laravel Integration: Publish the config and create a custom disk driver:

    // app/Providers/AppServiceProvider.php
    public function register()
    {
        Storage::extend('google', function ($app, $config) {
            $client = new \Google_Client();
            $client->setAuthConfig($config['keyFile']);
            $client->addScope(\Google_Service_Storage::STORAGE);
            $service = new \Google_Service_Storage($client);
            return new Filesystem(new GoogleCloudStorageAdapter(
                $config['bucket'],
                ['client' => $service]
            ));
        });
    }
    
  • Flysystem Events: Listen to file system events (e.g., preWrite, postDelete) for logging/auditing:

    $filesystem->addListener('preWrite', function ($event) {
        logger()->info('Uploading file', ['path' => $event->path()]);
    });
    
  • Caching: Use Flysystem’s caching layer to reduce API calls:

    $adapter = new GoogleCloudStorageAdapter('bucket', [
        'client' => $client,
        'cache' => new \League\Flysystem\Cached\Storage\CachedAdapter(
            $adapter,
            new \League\Flysystem\Cached\Storage\MemoryCache()
        ),
    ]);
    

Gotchas and Tips

Pitfalls

  1. Permissions:

    • Ensure the service account has Storage Object Admin or equivalent permissions.
    • Avoid using the default compute-engine service account for production (scope too broad).
  2. Bucket Naming:

    • Bucket names must be globally unique across all GCP projects.
    • Use lowercase letters, numbers, hyphens, and avoid underscores.
  3. Costs:

    • Monitor storage costs, network egress, and operations (e.g., GET, PUT).
    • Use regional buckets to reduce latency/costs for specific regions.
  4. CORS:

    • Configure CORS for browser-based uploads/downloads:
      $adapter->getClient()->storage()->bucket('bucket')->update(
          ['cors' => [
              ['origin' => ['*'], 'method' => ['GET', 'HEAD'], 'responseHeader' => ['*']],
          ]]
      );
      
  5. Timeouts:

    • Large files may hit PHP’s max_execution_time. Use streaming or chunked uploads.

Debugging

  • Enable Debugging:

    $client = new \Google_Client();
    $client->setDeveloperKey('your-api-key');
    $client->setApplicationName('MyApp/1.0');
    $client->setAuthConfig($keyFilePath);
    $client->setUseBatch(true); // For batch operations
    
  • Logging: Enable GCP logging for API calls:

    $client->setAccessType('offline');
    $client->setScopes([\Google_Service_Storage::STORAGE]);
    $client->setHandleAsSync(true); // For synchronous requests
    
  • Common Errors:

    • InvalidArgument: Check bucket name format or permissions.
    • Google_Auth_Exception: Verify keyFilePath and scopes.
    • Google_Service_Exception: Ensure the bucket exists and the object path is correct.

Extension Points

  1. Custom Metadata Handling: Extend the adapter to add custom metadata validation:

    class CustomGoogleCloudStorageAdapter extends GoogleCloudStorageAdapter {
        public function write($path, $contents, array $config = []) {
            $config['metadata']['customField'] = 'defaultValue';
            return parent::write($path, $contents, $config);
        }
    }
    
  2. Event Dispatching: Integrate with Laravel Events or custom listeners:

    $filesystem->addListener('postUpload', function ($event) {
        event(new FileUploaded($event->path(), $event->contents()));
    });
    
  3. Fallback Storage: Implement a fallback to local storage if GCS is unavailable:

    $adapter = new FallbackAdapter(
        new GoogleCloudStorageAdapter('primary-bucket', [...]),
        new LocalAdapter(new \League\Flysystem\Local\LocalFilesystem())
    );
    
  4. Async Operations: Use queues for background uploads/downloads:

    Queue::push(UploadToGCS::class, [
        'path' => 'file.jpg',
        'contents' => file_get_contents('local.jpg'),
        'disk' => 'gcs',
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport