spatie/flysystem-google-cloud-storage
Google Cloud Storage adapter for Flysystem v1 (PHP 8). A maintained fork adding modern PHP support and merged fixes. Use it to connect Flysystem’s filesystem API to GCS with Google’s client authentication.
composer require spatie/flysystem-google-cloud-storage
.env or Laravel's config/services.php):
'google' => [
'key' => env('GOOGLE_APPLICATION_CREDENTIALS_JSON'),
'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET'),
],
config/filesystems.php:
'disks' => [
'gcs' => [
'driver' => 'google',
'key' => env('GOOGLE_APPLICATION_CREDENTIALS_JSON'),
'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET'),
'project_id' => env('GOOGLE_CLOUD_PROJECT_ID'),
'root' => env('GCS_ROOT_PATH', ''), // Optional: Prefix for all paths
],
],
Storage facade:
use Illuminate\Support\Facades\Storage;
Storage::disk('gcs')->put('path/to/file.txt', 'file contents');
tests/ for edge cases (e.g., ACLs, custom metadata).config/filesystems.php for disk configuration.File Operations:
Storage facade or Flysystem's Filesystem directly:
// Upload
Storage::disk('gcs')->put('file.jpg', file_get_contents('local.jpg'));
// Download
$contents = Storage::disk('gcs')->get('file.jpg');
// Delete
Storage::disk('gcs')->delete('file.jpg');
Storage::disk('gcs')->writeStream('large-file.zip', fopen('local.zip', 'r'));
Directory Handling:
Storage::disk('gcs')->makeDirectory('folder/subfolder');
$files = Storage::disk('gcs')->files('folder/');
Metadata and ACLs:
Storage::disk('gcs')->put('file.txt', 'content', [
'metadata' => ['author' => 'John Doe'],
]);
google-cloud-storage v1.28+):
Storage::disk('gcs')->put('file.txt', 'content', [
'acl' => ['publicRead'],
]);
Laravel Filesystem Integration:
config/filesystems.php for seamless integration with:
Storage::disk('gcs')->url() (generates signed URLs if configured).Storage::disk('gcs')->temporaryUrl() (for time-limited access).'visibility' => 'public', // or 'private'
Customizing the Adapter:
use Spatie\FlysystemGoogleCloudStorage\GoogleCloudStorageAdapter;
class CustomGoogleAdapter extends GoogleCloudStorageAdapter {
public function customMethod() {
// ...
}
}
config/filesystems.php:
'gcs' => [
'driver' => 'custom-google',
'adapter' => CustomGoogleAdapter::class,
// ...
],
Environment-Specific Configs:
config/caching or environment variables for multi-environment setups:
'disks' => [
'gcs_prod' => [
'driver' => 'google',
'key' => env('GOOGLE_PROD_KEY'),
// ...
],
'gcs_dev' => [
'driver' => 'google',
'key' => env('GOOGLE_DEV_KEY'),
// ...
],
],
Fallbacks and Retries:
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
$retry = 3;
while ($retry--) {
try {
Storage::disk('gcs')->put('file.txt', 'content');
break;
} catch (\Exception $e) {
if ($retry === 0) throw $e;
sleep(Str::random(1) * 2); // Exponential backoff
}
}
Authentication Issues:
Google\Auth\Exception\InvalidCredentialsException..env or config/services.php.Bucket Permissions:
Google\Cloud\Storage\StorageException: 403 Forbidden.storage.objects.create or storage.objects.delete permissions.gsutil to test permissions:
gsutil acl ch -u "service-account@project.iam.gserviceaccount.com" gs://bucket-name
Path Handling:
$path = str_replace('\\', '/', trim($path, '/'));
Visibility Defaults:
private unless explicitly set to public.config/filesystems.php:
'gcs' => [
'driver' => 'google',
'visibility' => 'public', // or 'private'
// ...
],
Large File Uploads:
max_execution_time and memory_limit.Storage::disk('gcs')->writeStream('large-file.zip', fopen('local.zip', 'r'), [
'chunkSize' => 5 * 1024 * 1024, // 5MB chunks
]);
Enable GCS Logging:
GOOGLE_CLOUD_LOGGING environment variable to debug:
export GOOGLE_CLOUD_LOGGING=debug
Google\Cloud\Storage exceptions.Validate JSON Key:
gcloud auth activate-service-account --key-file=key.json
gsutil ls gs://your-bucket-name
Check Bucket Existence:
gsutil ls gs://your-bucket-name
Network Restrictions:
GOOGLE_CLOUD_PROXY environment variable:
export GOOGLE_CLOUD_PROXY=http://proxy.example.com:8080
Custom Metadata Handling:
class CustomGoogleAdapter extends GoogleCloudStorageAdapter {
public function put($path, $contents, array $options = []) {
$options['metadata'] = array_merge(
$options['metadata'] ?? [],
['custom_key' => 'custom_value']
);
return parent::put($path, $contents, $options);
}
}
Event Listeners:
Storage::disk('gcs')->put('file.txt', 'content');
// Trigger custom logic via events (e.g., `filesystem.stored`).
3
How can I help you explore Laravel packages today?