Weave 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

L5 Google Cloud Storage Laravel Package

websight/l5-google-cloud-storage

This Laravel 5 package integrates Google Cloud Storage into your application, providing a simple filesystem driver so you can read, write, and manage files on GCS using Laravel's native Storage API. Ideal for offloading uploads and assets to Google's cloud.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a thin Laravel 5 service provider that registers a Flysystem Google Cloud Storage driver with Laravel's Storage facade. It does not ship its own SDK; it wires the Flysystem GCS adapter into Laravel's filesystem manager, so treat it as glue rather than a full abstraction.

As of v1.1.0 the package's only meaningful change over the original 2016 release is a widened framework constraint: it now installs on Laravel 5.3 as well as 5.4. The provider code, driver name, and config keys are unchanged — anyone already on 5.4 gains nothing from the bump, and anyone on 5.3 gains only the ability to install it. There are no new features, no deprecations, and no breaking changes.

Minimal setup:

  1. Install the adapter and the package. In a Laravel 5 app:

    composer require websight/l5-google-cloud-storage:^1.1
    

    Pin ^1.1 explicitly if you're on 5.3 — older tags declare constraints that exclude it, and without a pin you can silently resolve to the pre-5.3 release and get a confusing "driver not supported" downstream. The package still expects an old superbalist/flysystem-google-cloud-storage (or equivalent) plus google/cloud-storage under the hood. Composer will likely resolve old versions — pin them deliberately on PHP 7.x, and expect conflicts on PHP 8.

  2. Register the provider manually. v1.1.0 predates package auto-discovery, so Laravel 5.3/5.4 both require this. Add to config/app.php:

    'providers' => [
        // ...
        Websight\GoogleCloudStorage\GoogleCloudStorageServiceProvider::class,
    ],
    
  3. Add a disk in config/filesystems.php pointing at the driver the package registers (commonly gcs or google-cloud-storage — check the provider source to confirm the exact driver string):

    'disks' => [
        'gcs' => [
            'driver' => 'gcs',
            'project_id' => env('GOOGLE_CLOUD_PROJECT'),
            'bucket' => env('GOOGLE_CLOUD_BUCKET'),
            'key_file' => env('GOOGLE_APPLICATION_CREDENTIALS'),
        ],
    ],
    
  4. Provide credentials via a service-account JSON file and set GOOGLE_APPLICATION_CREDENTIALS to its absolute path. Prefer this over embedding the path in config so you can swap environments.

  5. First use case — the package earns its keep only when you use it through the facade, not directly:

    Storage::disk('gcs')->put('exports/report.csv', $csv);
    $url = Storage::disk('gcs')->url('exports/report.csv');
    

Where to look first: open the service provider class itself. There are typically only a handful of lines — a filesystem extension registration and a config merge. That one file tells you the driver name, the config keys it recognizes, and which adapter class it instantiates. Compare it against the v1.0 tag; the v1.1.0 diff should be confined to composer.json, which is your signal that nothing else in this guide needs to change on upgrade.

Implementation Patterns

Use the disk, not the SDK. The whole point of the package is that Storage::disk('gcs') behaves like Storage::disk('local'). Keep GCS-specific calls out of your domain code by defining a single disk name in config and referencing it via a config value or constant:

$disk = Storage::disk(config('filesystems.cloud'));
$disk->put($path, $contents);

Separate public and private buckets. A common pattern is two disks — one for user-facing assets with public visibility, one for private uploads accessed only via signed URLs:

Storage::disk('gcs-public')->put($path, $file, 'public');
$signed = Storage::disk('gcs-private')->temporaryUrl($path, now()->addMinutes(10));

Store paths, not URLs, in the database. Persist the object path and derive the URL at render time. Bucket names and CDN hostnames change; paths don't. Wrap access in a small helper or model accessor so you can migrate providers later without a data migration.

Validate uploads before they hit GCS. Flysystem's putFile/putFileAs will happily stream whatever you give it. Do file-type and size validation in the form request, then hand the validated UploadedFile to the disk. Use putFileAs to control the destination filename and avoid collisions:

$path = $request->file('avatar')->storeAs(
    "users/{$user->id}", 'avatar.jpg', 'gcs-public'
);

Stream large files rather than buffering. For big exports, use writeStream with a temp stream instead of put with a string, so you aren't holding the payload in memory:

$stream = fopen('php://temp', 'r+');
// ... write rows
rewind($stream);
Storage::disk('gcs')->writeStream($path, $stream);

Testing. Point the disk at a local driver in phpunit.xml or a testing service provider, and assert against Storage::fake(). Never let tests call real GCS. Since the package only registers a driver, faking the disk name is enough — you don't need the package installed at test time.

Integration with queues. GCS writes are network calls. Offload uploads, transformations, and cleanup to queued jobs, and pass the object path (not the UploadedFile) between jobs, since the temp file is gone by the time the job runs. Upload to GCS immediately in the request, then queue post-processing.

Upgrading to v1.1.0 is a no-op for existing installs. There is nothing to migrate: no config keys renamed, no driver string changed, no provider method signatures touched. Bump the constraint, run composer update websight/l5-google-cloud-storage, and clear config cache. If you were previously pinned below 1.1 to force resolution on 5.4, you can drop that pin — but only after confirming the transitive google/cloud-storage version doesn't shift with it.

Gotchas and Tips

This package is effectively abandoned (last release 2016, with v1.1.0 as a one-line compatibility patch). The real risk is dependency drift, not the provider code. The google/cloud-storage and Flysystem adapter versions it pulls are years old and will fight modern PHP and Laravel. Before adopting it, run composer why-not and consider replacing the provider with a two-line manual driver registration or a maintained package such as spatie/flysystem-google-cloud-storage or league/flysystem-google-cloud-storage. The provider is so small that vendoring it into your app is often safer than depending on it.

v1.1.0 widens the constraint but does not modernize anything. The release note reads "allow using in Laravel 5.3 projects" — that means an illuminate/support (or equivalent) range change and nothing more. Don't read it as renewed maintenance: it still targets Laravel 5.x only and offers no path to 5.5+ auto-discovery, 6.x, or PHP 8. When you run composer outdated, expect this package to stay red.

Driver name mismatch is the #1 failure. If Storage::disk('gcs') throws "Driver [gcs] is not supported," either the provider isn't registered, the config driver string doesn't match what the provider registers, or the package didn't autoload because the provider was added after config caching. Run php artisan config:clear and confirm the exact driver string in the provider source. This is the most likely symptom of an accidental downgrade to a pre-5.3 tag, so check composer show websight/l5-google-cloud-storage reports 1.1.0 first.

Config caching hides env changes. On Laravel 5, config:cache bakes env values in. Changing GOOGLE_APPLICATION_CREDENTIALS won't take effect until you clear it. In deployed environments, verify the JSON file actually exists at the path the process can see — containers frequently mount secrets somewhere the app user can't read.

Credential resolution order matters. If you supply both a key file and ambient credentials, you can end up authenticating as the wrong service account. Be explicit: set the key file path, and unset other Google env vars in the environment to avoid surprises. Check the resulting identity if 403 errors appear on a bucket you believe is public.

Visibility is bucket-policy dependent. Passing 'public' sets an object ACL, but if the bucket has uniform bucket-level access or public access prevention enabled, it will fail or be silently ignored. Don't assume url() produces a publicly reachable link — test it with an unauthenticated curl, not your browser session.

Public URL caching. Flysystem's url() for GCS simply composes a storage.googleapis.com path; it does not check existence or permissions. Caching these URLs is fine, but caching the result of a 403 is not — make sure your own HTTP cache doesn't pin a failure after you fix IAM.

Timeouts and retries. The underlying HTTP client defaults are aggressive for large uploads. Wrap large writeStream/put calls and retry with backoff on 5xx and 429; treat 4xx as terminal. Don't retry inside a tight loop where the SDK already retried.

Path normalization. Flysystem expects forward slashes and no leading slash. Building paths with DIRECTORY_SEPARATOR on Windows dev machines produces objects with backslashes that look fine locally and break in production. Use sprintf('%s/%s', ...) or Storage::path-style helpers.

Extension point. The provider is a single class; the cleanest escape hatch is to extend or copy it and re-register a custom driver with the same name, overriding Storage::extend. That lets you add logging, custom retries, or a different adapter without forking the package — important since upstream fixes are unlikely. Note that v1.1.0 gives you no reason to fork for compatibility reasons alone; fork only for behaviour.

Migration path. Because this package only binds a driver, migrating to a maintained adapter is usually a one-file change: keep the disk name and config keys, swap the provider and adapter class. If you follow the "store paths, not URLs" pattern above, no application code or stored data needs to change.

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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log