Download the PHP package centralnic-reseller/php-sdk without Composer

On this page you can find all versions of the php package centralnic-reseller/php-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package php-sdk

php-sdk

semantic-release Release Packagist PHP from Packagist License: MIT PRs welcome codecov

This module is a connector library for the insanely fast CNIC Backend APIs (CentralNic Reseller, internet.bs, moniker). Do not hesitate to contact us in case of questions.

Resources

Usage

Requirements: PHP 8.3 or newer with the curl and intl extensions. curl carries every request; intl provides the idn_to_ascii() that converts internationalized domain names to punycode. Both are declared in composer.json, so Composer refuses to install on a runtime that is missing either.

Idiomatic code for the current major, whatever that is when you read this — this section is kept up to date rather than pinned to the version that introduced the factory:

Two brand differences the snippet is deliberately explicit about:

Type against the interfaces, not the concrete classes. Depending on CNIC\ResponseInterface, CNIC\ColumnInterface, CNIC\RecordInterface and CNIC\LoggerInterface is what keeps future majors from breaking you; code that reaches for CNIC\CNR\Response or uses method_exists() fallbacks is what does not survive them.

Configuring a client up front

When the connection settings are already known — the usual case in a registrar module reading them from stored configuration — build the brand's SocketConfig and hand it to the factory. This is the recommended route, and the one to reach for whenever the settings do not depend on anything the client does:

Two reasons to prefer it over the setter sequence:

The parameter is optional and every brand takes its own config type — ClientFactory::moniker() wants a MONIKER\SocketConfig, not an IBS one, because the endpoints are what differ between those two brands. ClientFactory::cnr() with no argument is fully supported, as are the fluent setters shown earlier; use them when the settings are not yet known at construction time. Anything that is not connection configuration — the response context, a custom logger or log sink, the user agent, a replacement transport — keeps its setter either way.

Reading the rows of a list response

A response is fully assembled by the time you hold one, and read-only from then on. Walk its records with foreach — the response is iterable — or address them by index:

Rows are data only. What the API sends about the response — CNR's TOTAL/FIRST/LAST/COUNT/LIMIT, IBS/Moniker's transactid/status/message/code and count keys (domaincount, total_*) — is not a column and is not part of any row. Those keys appear in no getColumnKeys(), no getColumns(), no getColumn() and in no record. Read that metadata where it belongs: isSuccess()/getCode()/getDescription() for the status, getHash() for the raw value, and the paginator plus the four primitives below for the counters.

[!IMPORTANT] This changed in v33.0.0, and it is the change most likely to break an integration written against an older major. Until v32 the counters were registered as one-cell columns sitting beside your data columns, so they showed up inside every record. Code like $r->getRecord(0)->getData()["TOTAL"] therefore worked, and now returns null. Ask the response instead — no string parsing, and null rather than a stand-in when the response is not a paginated list:

Full before/after, including the row-shape and null consequences: Migration Guide → v33.0.0.

The exclusion matches exact key names, so CNR lookalikes are still data. Only the five names above are reserved on CNR. A command that answers its own per-entity counters keeps them as ordinary columns — QueryEventList sends property[events total] and property[events count], which the parser folds to EVENTSTOTAL and EVENTSCOUNT — and so does CNR's COLUMN descriptor, the entry naming which columns the list carries. EVENTSTOTAL is not a renamed TOTAL: the two can hold different numbers, and only TOTAL feeds getRecordsTotalCount() and the paginator.

One consequence worth coding against: because those keys are columns, they size the record list, so a CNR list window that came back empty can still report a single record built entirely out of them.

So bound the loop on the data key you actually read rather than on the record count, and take the row count from the metadata accessors:

Paging through a list

getPagination() hands you a CNIC\Paginator — a value object over the window this response describes:

The four numbers it is built from stay on the response, because they are what the brand read off the wire: getFirstRecordIndex(), getLastRecordIndex(), getRecordsTotalCount() and getRecordsLimitation(). Each answers null when this response carries no such metadata, which is how a non-list response says so rather than reporting itself as page 1 of something. getRecordsCount(), separately, is how many rows you actually got.

For CNR you rarely need any of it by hand — CNR\Client::requestNextResponsePage() and requestAllResponsePages() walk the offsets for you.

Ask for the type you want. getDataByKey()/getDataByIndex() return mixed, because an IBS/Moniker cell may legitimately carry a nested array or object. When you expect a plain value, the typed accessors save you the check — each returns null for a missing key, an out-of-range index, or a value of the wrong type, so there is nothing to narrow by hand and no annotation to write:

foreach keeps its position in the loop rather than on the response, so iterating is repeatable, needs no rewind step, and two places iterating the same response cannot interfere. If you are coming from a version with getNextRecord()/rewindRecordList(), see Migration Guide → v31.0.0.

Debug output

enableDebugMode() writes one record per request to standard output. Two seams let you take it somewhere else, and they are independent:

Order matters between the two: setLogSink() rebuilds the brand logger around your sink, so call it before setCustomLogger(), not after.

LoggerInterface::format() returns the record rather than printing it, so you can route SDK debug output into your own logging without reimplementing a brand's format — and assert on it in your own tests without output buffering. Sensitive command values are already masked before they reach the formatter — PASSWORD and AUTH on CNR, password and transferAuthInfo on IBS/Moniker.

Testing your integration offline

Nothing in the request lifecycle needs a network. setTransport() swaps the cURL layer for anything implementing CNIC\TransportInterface, so you can hand the client a canned API response and still exercise the real command building, parsing and logging:

Each of the client's three collaborators has a matching reader, so your own tests can assert the wiring took effect rather than reaching into the client: getTransport(), getLogger() and getSocketConfig(). That is how you confirm a custom logger survived the setLogSink()/setCustomLogger() ordering rule above, or that the transport double is the one in place:

For working, runnable examples per brand — including the CNR session flow (saveSession()/reuseSession() across two stateless requests) — see examples/app_CNR.php, examples/app_IBS.php and examples/app_MONIKER.php. Those are not part of the Composer package — clone the repository to run them, as described under Running the Demo Application.

Date & time values

The APIs declare their date columns in UTC and emit two shapes: a full timestamp (2026-07-25 07:46:34, optionally with a fractional-second part, as CNR sends) and a bare calendar date (2030/07/17, as internet.bs/Moniker send). CNIC\ApiDateTime parses both into one flat, immutable struct, and accepts either - or / as the date separator — consistently within one value, so 2026-02/20 is refused. $date/$dateTime always come back with -, regardless of which one the source used:

Field Type CNR 2026-07-25 07:46:34 internet.bs / Moniker 2030/07/17
ts int\|null 1784965594 null — exact instant unknown
date string 2026-07-25 2030-07-17 — always -, even here
dateTime string\|null 2026-07-25 07:46:34 null
tz string UTC UTC
raw string 2026-07-25 07:46:34 2030/07/17 — verbatim input

A bare calendar date names no instant, so ts and dateTime are both null for one — deliberately, rather than defaulting to midnight, which would be a fabricated instant indistinguishable from a real one. date is always populated, so there is unconditionally something to print; $dt->ts === null (or isDateOnly()) is the unambiguous test.

raw keeps whatever the source sent, including a fractional-second part dateTime discards. It is for display, logging and round-trip fidelity only — compare and sort on ts or date, never on raw, since "2026/02/20" sorts wrong against "2026-03-01" as plain strings.

Parsing is strict. Values PHP's own date handling would silently roll over into a different instant — 2026-02-30 becoming 2026-03-02, 2026-13-45 becoming 2027-02-14, 0000-00-00 becoming -0001-11-30 — are refused with a CNIC\Exception\InvalidDateTimeException, as are offset-bearing values (never silently relabelled UTC). Use ApiDateTime::tryFrom() when a null is preferable to an exception:

[!NOTE] This is a parser, not a formatter. Responses are not rewritten: getPlain(), getHash() and getListHash() keep returning the raw API strings verbatim — internet.bs/Moniker dates keep their / separator — and this type is opt-in at the point where a value is actually used. There is no locale formatting and this type never touches ext-intl — presenting a value in the viewer's timezone is a display concern for the consuming application:

CNIC\Record::getDateTimeByKey() and CNIC\Column::getDateTimeByIndex() do that narrowing for you, right where you already read a value — no null check on a non-string, missing, or unparsable value needed beyond the returned ?ApiDateTime itself:

Run composer demo:datetime for a runnable tour — it needs no credentials and makes no API calls.

Dev Container

If you want to contribute, we recommend Visual Studio Code with the Dev Containers extension: open the repository and choose Reopen in Container. Docker and VS Code are the only host prerequisites — PHP 8.3 with Xdebug, Composer, Node, and the whole lint and test toolchain come with the container.

The shared half of that environment (zsh with the team prompt, commitizen, the gh credential helper, persistent shell history, dependency installation and the on-attach toolchain banner) comes from the devbase Feature, so this repository's own .devcontainer/ only adds what is specific to PHP.

Environment variables (env.sh)

The devcontainer looks for an env.sh file in the workspace root and automatically sources it in two places:

  1. Every new integrated-terminal session — the file is sourced via ~/.zshenv so credentials are available as soon as you open a terminal, without a manual source env.sh.
  2. PHPUnit runs triggered from the VSCode UI — the PHPUnit wrapper script sources env.sh before invoking PHP, so IDE-triggered tests see the same variables as composer test does from the terminal.

env.sh is listed in .gitignore and will never be committed. Create it once in the workspace root with the variables you need — copy env.example.sh as a starting point.

[!NOTE] The auto-loading takes effect for new terminal sessions. If your terminal was already open when you created or updated env.sh, run source env.sh once in that session or open a new terminal.

Running the Demo Application

To run the demo application, follow these steps:

  1. Set your credentials — create an env.sh in the workspace root (see Environment variables (env.sh)), or replace the placeholders inside the demo file directly.

  2. Run the demo for the brand you want:

    These are thin wrappers around plain PHP — edit the file listed on the right to change a demo, or run it directly without any tooling (php -f examples/app_CNR.php).

CI / Testing

CI is powered by reusable GitHub Actions workflows. The test matrix covers:

PHP Version Status
8.3 ✓
8.4 ✓
8.5 ✓

The matrix is configured via the repository variable RTLDEV_MW_CI_PHP_MATRIX and tracks the actively-maintained PHP versions — new versions are added as they enter active support and dropped once they reach end-of-life.

[!NOTE] composer.json requires php: >=8.3.0, which sets the minimum only — the SDK runs on every version in the matrix above. Note that the source code itself is deliberately held to PHP 8.3 language features (Rector is pinned to 8.3) because the SDK also ships inside ionCube-encoded WHMCS integrations that cannot execute newer syntax. In short: runs on 8.3–8.5, but only uses 8.3-level language features. Full rationale: PHP Version Policy.

Maintainers

License

This project is licensed under the MIT License - see the LICENSE file for details.


All versions of php-sdk with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3.0
ext-curl Version *
ext-intl Version *
centralnic-reseller/idn-converter Version ^2.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package centralnic-reseller/php-sdk contains the following files

Loading the files please wait ...