PHP client for the Gcore API.
Gcore publishes an official Python SDK but no PHP one. This package covers CDN, DNS and FastEdge. The API surface is generated from Gcore's published OpenAPI specifications; the transport, retry, and hydration layers are hand-written.
- PHP 8.2 or newer
- ext-json
composer require srustamov/gcore-phpuse Gcore\Client;
$gcore = new Client(apiKey: getenv('GCORE_API_KEY'));
$zone = $gcore->dns->zones->get('example.com');
echo $zone->name;The API key falls back to the GCORE_API_KEY environment variable when the
argument is omitted.
List endpoints return a lazy Paginator. Iterating it walks every page, so you
never deal with offsets yourself.
foreach ($gcore->dns->zones->list() as $zone) {
echo $zone->name, PHP_EOL;
}Pagination is driven through the returned object, not through the call that creates it:
$paginator = $gcore->dns->zones->list();
$firstPage = $paginator->page(limit: 20); // one page
$everything = $paginator->all(); // materialize all pages
$total = $paginator->count(); // server-reported totalFilters, on the other hand, are arguments. Array filters repeat the query key, which is what the API expects:
$gcore->dns->zones->list(orderBy: 'name', id: [1, 2]);
// GET /dns/v2/zones?order_by=name&id=1&id=2$gcore->dns->rrsets->create('example.com', 'www.example.com', 'A', [
'ttl' => 300,
'resource_records' => [
['content' => ['1.2.3.4']],
],
]);
foreach ($gcore->dns->rrsets->list('example.com') as $rrset) {
echo $rrset->name, ' ', $rrset->ttl, PHP_EOL;
}Request bodies are associative arrays. Their shapes are documented as
array{...} PHPDoc on each method, so PhpStorm and PHPStan can check them
without the library shipping a parameter class per endpoint.
Models expose typed properties for everything the specification documents, and
raw() for everything else. A field Gcore adds after this release is still
reachable without waiting for a new version.
$zone = $gcore->dns->zones->get('example.com');
$zone->name; // typed
$zone->raw()['brand_new_field']; // whatever the API actually returnedtoArray() and jsonSerialize() return the same raw payload, so a model
round-trips exactly what the server sent.
Every failure is a Gcore\Exception\GcoreException. Non-2xx responses raise a
subclass of ApiException chosen by status code.
use Gcore\Exception\NotFoundException;
use Gcore\Exception\RateLimitException;
try {
$gcore->dns->zones->get('missing.example');
} catch (NotFoundException $e) {
echo $e->statusCode; // 404
echo $e->rawBody; // the response body, verbatim
} catch (RateLimitException $e) {
// already retried per the retry policy before reaching you
}| Status | Exception |
|---|---|
| 400 | BadRequestException |
| 401 | AuthenticationException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 409 | ConflictException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| 5xx | ServerException |
| network, timeout | ConnectionException |
The three Gcore products in scope document no shared error body, so the message
is taken from whichever of message, error, detail, or errors is present,
falling back to the HTTP reason phrase. rawBody is always kept.
$gcore = new Client(
apiKey: '...',
baseUrl: 'https://api.gcore.com',
timeout: 30.0,
maxRetries: 2,
headers: ['X-Trace' => 'abc'],
);Requests retry on 408, 409, 429, and 5xx responses, and on connection errors,
with exponential backoff plus jitter capped at 8 seconds. A numeric
Retry-After header wins over the computed delay. Any single call can override
the defaults:
use Gcore\RequestOptions;
$gcore->dns->zones->get('example.com', new RequestOptions(timeout: 5.0, maxRetries: 0));| Product | Resources | Models | Accessor |
|---|---|---|---|
| CDN | 18 | 220 | $gcore->cdn |
| DNS | 10 | 50 | $gcore->dns |
| FastEdge | 7 | 30 | $gcore->fastedge |
| Cloud | — | — | Not planned for v1 |
This section is for working in the repository. The generator is not part of the
installed package — composer require ships src/ and nothing else.
src/Cdn, src/Dns and src/Fastedge are generated. Do not edit them by hand —
change the emitters under codegen/ and regenerate:
php codegen/bin/generate.php dns # or cdn, or fastedge
vendor/bin/php-cs-fixer fix
vendor/bin/phpunitFormatting is a required step, not a tidy-up: the emitters produce output that php-cs-fixer then normalizes, so the zero-diff check below only holds once it has run.
Where the naming rules cannot produce a good name — CDN puts three separate
collections under one Logs uploader tag, for instance — codegen/overrides.php
maps the path to the name it should have.
Regenerating an unchanged specification produces no diff, and CI enforces that, so a hand-edit under a generated directory fails the build rather than being silently erased by the next run.
php codegen/bin/check-drift.php reports when a vendored specification has
fallen behind the published one.
MIT