Skip to content Documentation index for agents (llms.txt)
Glotto Beta
Get started

PHP

The PHP SDK is an idiomatic, Composer-installable client emitted from the same GlottoIR as every other target. Files declare strict_types=1, models are typed-property objects with fromJson, and PHPDoc is generated from the operation prose in the spec.

Manual pages expose typed items, the full response and explicit continuation. A trailing RequestOptions controls headers, deadlines, retries, extra parameters and cooperative cancellation. Binary operations return an owned Core\BinaryDownload with bounded readAll, pipe, response metadata and close; foreach closes on break or error. See pagination, request retries and controls, streaming, and file transfers.

Quickstart

composer require your-org/petstore
<?php
require 'vendor/autoload.php';

$client = new Petstore\Client(token: '<token>');
$result = $client->pets->get('...');
var_dump($result);

Resource objects

Operations are camelCase methods on resource objects — $client->pets->get($id), $client->pets->photos->add(...) — the Stripe-PHP service-accessor shape, rather than flat snake_case methods.

PSR-18 transport

The client sends requests through an injectable PSR-18 HTTP client (Guzzle by default), so the transport is swappable and mockable — the PHP-ecosystem standard, the analogue of C#’s injectable HttpClient.

Typed errors

Non-2xx responses throw ApiError, an \Exception hierarchy carrying the parsed, typed error body; discriminated-union response bodies resolve to the right concrete type. See Errors.

Pagination

List methods return a lazy iterator (foreach) that walks every page, advancing the cursor for you. See Pagination.

Retries & backoff

Transient failures (5xx, 429, transport errors) retry with exponential backoff and jitter, configurable per client. See Retries & timeouts, Streaming, and Authentication.

Unknown response fields

Your API can add a response field without it being a breaking change — but a generated class has no promoted property to put it in, and its fromJson factory reads only the fields it declares. The generated models keep it instead: a field the SDK wasn’t generated from is retained on decode, readable through an accessor, and written back out when the model is re-serialized.

$pet = $client->pets->createPet($body);

// A field your API started returning after this SDK was generated.
$species = $pet->extraFields()['species'] ?? null;

// Re-encoding preserves it — a read-modify-write never silently drops it.
$json = json_encode($pet);

extraFields() returns an array<string, mixed>, so nested objects and lists survive intact, and retention is recursive.

One caveat from PHP’s JSON decoder: json_decode($body, true) represents an empty JSON object and an empty array identically, so an unknown field whose value is {} round-trips as []. Every other shape — nested objects, lists, scalars, null — round-trips unchanged.

Your existing construction still compiles: the storage is a private field assigned after construction, so the promoted constructor is untouched.

The retained fields are read-only by design. To send a field your spec doesn’t model yet, use the per-call extra-body escape hatch rather than writing to the retained bag.