google/cloud-storage
Idiomatic PHP client for Google Cloud Storage. Upload/download objects, manage buckets and permissions (ACLs), use a gs:// stream wrapper, and integrate with Google Cloud PHP authentication. Great for backups, archival, and serving large files.
Installation:
composer require google/cloud-storage
Add to composer.json under require or require-dev based on your needs.
Authentication:
gcloud auth application-default login
.env:
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
use Google\Auth\ApplicationDefaultCredentials;
$credentials = ApplicationDefaultCredentials::getCredentials();
First Use Case: Upload a file to a bucket with public access:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient();
$bucket = $storage->bucket('my-bucket-name');
$bucket->upload(
fopen('/path/to/local/file.txt', 'r'),
['predefinedAcl' => 'publicRead']
);
Key Files:
$bucket = $storage->createBucket('new-bucket-name', [
'storageClass' => 'STANDARD',
'location' => 'US',
]);
$bucket->delete();
foreach ($storage->buckets() as $bucket) {
echo $bucket->name() . "\n";
}
// Upload from file
$bucket->upload(fopen('local.txt', 'r'));
// Download to file
$object = $bucket->object('remote.txt');
$object->downloadToFile('local_copy.txt');
gs:// Wrapper:
$storage->registerStreamWrapper();
$contents = file_get_contents('gs://my-bucket/file.txt');
$object->update([
'metadata' => [
'author' => 'John Doe',
'description' => 'Sample file',
],
]);
$bucket->upload(fopen('file.txt', 'r'), [
'predefinedAcl' => 'publicRead', // or 'authenticatedRead', 'private'
]);
$bucket->update([
'retentionPeriod' => 365, // days
'retentionEffectiveTime' => new DateTime('now'),
]);
$bucket->update([
'lifecycleRules' => [
[
'action' => ['type' => 'SetStorageClass', 'storageClass' => 'COLDLINE'],
'condition' => ['age' => 90],
],
],
]);
$url = $object->signedUrl(new DateTime('+1 hour'));
// Use $url to share access without exposing credentials
foreach ($bucket->objects() as $object) {
echo $object->name() . "\n";
}
SplObjectStorage or ReactPHP for concurrent operations:
$loop = React\EventLoop\Factory::create();
$connector = new React\Socket\Connector($loop);
// Integrate with google/cloud-storage streams for async I/O
Service Provider Binding:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(StorageClient::class, function ($app) {
return new StorageClient([
'keyFilePath' => $app['config']['services.google.key_file'],
]);
});
}
Configurable Bucket Names:
// config/services.php
'google' => [
'storage' => [
'default_bucket' => env('GOOGLE_STORAGE_BUCKET', 'default-bucket'),
],
];
Facade for Convenience:
// app/Facades/GoogleStorage.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class GoogleStorage extends Facade
{
protected static function getFacadeAccessor()
{
return 'google.storage';
}
}
File Upload Middleware:
// app/Http/Middleware/UploadToGCS.php
public function handle($request, Closure $next)
{
if ($request->hasFile('avatar')) {
$storage = app(StorageClient::class);
$bucket = $storage->bucket(config('google.storage.default_bucket'));
$bucket->upload($request->file('avatar')->getRealPath());
}
return $next($request);
}
Event-Driven Workflows: Use Laravel Events + Google Cloud Pub/Sub to trigger actions on uploads:
// Listen for file uploads and process via queue
event(new FileUploaded($filePath));
Authentication Issues:
Google\Auth\Exception\GoogleAuthExceptionGOOGLE_APPLICATION_CREDENTIALS is set or ADC is configured. For Laravel, use google/cloud-core for unified auth:
use Google\Auth\Credentials\ServiceAccountCredentials;
$credentials = ServiceAccountCredentials::fromKeyFile(
$keyFilePath,
['scopes' => [Storage::SCOPE_CLOUD_PLATFORM]]
);
$storage = new StorageClient(['credentials' => $credentials]);
Stream Wrapper Quirks:
file_get_contents('gs://...') fails with InvalidArgumentException.$storage->registerStreamWrapper();
touch() to create empty objects:
$object = $bucket->object('empty.txt');
$object->update(['contentType' => 'text/plain']);
$object->touch();
Deprecated Options:
keyFile/keyFilePath in newer versions (marked deprecated in v1.48.4). Use credentials instead:
$storage = new StorageClient([
'credentials' => $credentials,
]);
Path Traversal:
gs://bucket/../../../etc/passwd.Soft Delete Confusion:
restore() or undelete():
$object->restore(); // Recover from soft delete
$object->undelete(); // Same as restore()
Retry Behavior:
$storage = new StorageClient([
'retry' => [
'max_attempts' => 3,
'timeout' => 30.0,
],
]);
Hierarchical Namespace (HNS):
$bucket = $storage->bucket('legacy-bucket', [
'hierarchicalNamespace' => false,
]);
Enable Debug Logging:
putenv('GOOGLE_CLOUD_DEBUG=1');
// Or set in .env:
// GOOGLE_CLOUD_DEBUG=1
Logs will appear in stderr or Laravel’s log channel.
Validate API Responses:
getMetadata() for HTTP status codes:
$object->update(['metadata' => [...]]);
$metadata = $object->getMetadata();
if ($metadata['http
How can I help you explore Laravel packages today?