Skip to content

GcsClient

Minimal Google Cloud Storage REST client authenticating with an HMAC key pair (GCS’s “interoperability” auth mode, meant for exactly this kind of S3-like tool) rather than a service-account OAuth2/JWT flow, no google/cloud-storage dependency, no token exchange round-trip, just the operations a session or filesystem backend needs against the XML API: get, put, delete, head and list a bucket.

Anything beyond those, resumable upload, ACLs, object versioning, is deliberately absent, but reachable: GcsClient::request() performs the HMAC signing and hands back the raw PSR-7 response, so a caller can implement the operation it needs without reimplementing the signature.

final class GcsClient implements ListableObjectStoreClientInterface

ImplementsListableObjectStoreClientInterface
SourceGcsClient.php

public function __construct(ClientInterface $httpClient, string $accessKey, string $secretKey, string $bucket, string $endpoint = 'https://storage.googleapis.com', Psr17Factory $psr17 = new Psr17Factory(…)): mixed

ParameterTypeDescription
$httpClientClientInterface
$accessKeystring
$secretKeystring
$bucketstring
$endpointstring
$psr17Psr17Factory

Returns mixed

MethodDescription
delete(string $object): voidA 404 returns normally, so deleting an object that is not there is not an error; any other 4xx/5xx raises GcsStorageException.
get(string $object): ?stringA 404 from the XML API is reported as null; every other 4xx/5xx raises GcsStorageException, as does a transport failure.
head(string $object): ?ObjectMetadataObject metadata without transferring the body, or null if the object does not exist.
listObjects(string $prefix = '', string $delimiter = '', ?string $continuationToken = null, int $maxKeys = 1000): ObjectListingThe XML interoperability API paginates with a marker rather than an opaque continuation token: $continuationToken is sent as marker and, on a truncated result, this returns NextMarker as ObjectListing::$nextContinuationToken (falling back to the last listed key if GCS reports truncation without one).
put(string $object, string $body): voidThe whole body is sent in one PUT as application/octet-stream; there is no resumable upload here.
request(string $method, string $object = '', array<string, string> $query = [], ?string $body = null, string $contentType = ''): ResponseInterfaceSend an arbitrary signed request to this client’s bucket and return the raw response, for operations this class does not model itself.

public function delete(string $object): void

A 404 returns normally, so deleting an object that is not there is not an error; any other 4xx/5xx raises GcsStorageException.

Best-effort: a key that does not exist is not an error.

ParameterTypeDescription
$objectstring
ThrowsWhen
ObjectStoreExceptionOn a transport or provider failure.

public function get(string $object): ?string

A 404 from the XML API is reported as null; every other 4xx/5xx raises GcsStorageException, as does a transport failure.

No retry is attempted.

ParameterTypeDescription
$objectstring

Returns ?``string

ThrowsWhen
ObjectStoreExceptionOn a transport or provider failure, as distinct from a missing object.

public function head(string $object): ?ObjectMetadata

Object metadata without transferring the body, or null if the object does not exist.

ParameterTypeDescription
$objectstring

Returns ?ObjectMetadata

public function listObjects(string $prefix = '', string $delimiter = '', ?string $continuationToken = null, int $maxKeys = 1000): ObjectListing

The XML interoperability API paginates with a marker rather than an opaque continuation token: $continuationToken is sent as marker and, on a truncated result, this returns NextMarker as ObjectListing::$nextContinuationToken (falling back to the last listed key if GCS reports truncation without one).

With $delimiter empty, every matching key comes back as an ObjectSummary in ObjectListing::$objects — a fully recursive listing. With $delimiter set, a key is only listed that way when $prefix (plus nothing else) reaches it before the first occurrence of $delimiter; everything past that point is collapsed into one entry per distinct prefix-up-to-and-including-the-delimiter in ObjectListing::$commonPrefixes instead — the “one directory level” view every provider’s own console uses.

$continuationToken must be null on the first call and, for a truncated result, ObjectListing::$nextContinuationToken verbatim on the next — it is opaque, provider specific, and never meant to be inspected or constructed by a caller.

ParameterTypeDescription
$prefixstring
$delimiterstring
$continuationToken?``string
$maxKeysint

Returns ObjectListing

ThrowsWhen
ObjectStoreExceptionIf GCS answers 4xx/5xx, or its response body was not the XML this expects.

public function put(string $object, string $body): void

The whole body is sent in one PUT as application/octet-stream; there is no resumable upload here.

The bucket must already exist.

ParameterTypeDescription
$objectstring
$bodystring
ThrowsWhen
ObjectStoreExceptionIf the write does not succeed.

public function request(string $method, string $object = '', array<string, string> $query = [], ?string $body = null, string $contentType = ''): ResponseInterface

Send an arbitrary signed request to this client’s bucket and return the raw response, for operations this class does not model itself.

ParameterTypeDescription
$methodstring
$objectstring
$queryarray``<``string``, ``string``>
$body?``string
$contentTypestring

Returns ResponseInterface