Snippets
Minimal copy-paste blocks for flags, configs, kill switches, experiments and i18n.
Minimal copy-paste blocks, grouped by the registry taxonomy. These are the same leaves the docs get op returns.
release
release / flags
Read a flag with a user-bound Client. Assumes Shipeasy\configure() ran at
startup — see Installation.
use Shipeasy\Client;
// construct once per callsite (cheap; binds the user)
$client = new Client($currentUser);
$enabled = $client->getFlag(
'{{FLAG_KEY}}', // gate name
false, // optional $default — returned ONLY when unevaluable
); // (SDK not ready / flag not in blob), NOT when the gate is offrelease / configs
Read a dynamic config value (with a fallback for the absent case). Assumes
Shipeasy\configure() ran at startup — see Installation.
use Shipeasy\Client;
// construct once per callsite (cheap; binds the user)
$client = new Client($currentUser);
$value = $client->getConfig(
'{{CONFIG_KEY}}', // config name
['headline' => 'Welcome'], // optional $default — returned when the config key is absent
);release / killswitches
Read a kill switch (global panic boolean). Assumes Shipeasy\configure() ran at
startup — see Installation.
use Shipeasy\Client;
// construct once per callsite (cheap; binds the user)
$client = new Client($currentUser);
$panic = $client->getKillswitch(
'{{KILLSWITCH_KEY}}', // kill switch name
null, // optional $switchKey — read a named per-key override
); // (null = top-level value; unconfigured key falls back to it too)release / experiments
Read an experiment assignment, then track the conversion on the same bound
Client. Assumes Shipeasy\configure() ran at startup — see Installation.
use Shipeasy\Client;
// construct once per callsite (cheap; binds the user)
$client = new Client($currentUser);
$r = $client->getExperiment(
'{{EXPERIMENT_KEY}}', // experiment name
['color' => 'blue'], // $defaultParams — params returned when the user isn't enrolled
);
$color = $r->inExperiment ? $r->params['color'] : 'blue';
// track() is on the same bound Client — the unit comes from the bound user, so
// there is no userId argument.
$client->track(
'{{SUCCESS_EVENT}}', // event name (the experiment's success metric)
['amount' => 49], // optional $props — event properties (default [])
);metrics
metrics / track
Track a metric/conversion event from the bound Client. Metrics in the dashboard
are computed from these events. Assumes Shipeasy\configure() ran at startup —
see Installation.
Track an event
use Shipeasy\Client;
// construct once per callsite (cheap; binds the user)
$client = new Client($currentUser);
// track($event, $props = [])
// $event — the event your metric is built on (required)
// $props — optional payload; numeric/string fields you can sum/filter on
// in a metric (private attributes are stripped before egress)
$client->track('{{EVENT_NAME}}', ['amount' => 49, 'currency' => 'usd']);Fire-and-forget (never blocks your response) and a no-op under
Shipeasy\configureForTesting() / Shipeasy\configureForOffline(). The unit is
the bound user (user_id, else anonymous_id); with no unit the call is a no-op.
Track without properties
use Shipeasy\Client;
// construct once per callsite
$client = new Client($currentUser);
$client->track('{{EVENT_NAME}}'); // $props are optionali18n
i18n / setup
i18n is rendered in the browser. From PHP, emit the loader <script> tag with
the public client key and the {{PROFILE}} profile into your <head>.
Assumes Shipeasy\configure() ran at startup — see Installation.
use function Shipeasy\bootstrapScriptTag;
use function Shipeasy\i18nScriptTag;
// Package-level helpers — backed by the SDK that configure() set up.
// $clientKey is the PUBLIC client key (NOT the server key).
$head = bootstrapScriptTag(
['user_id' => 'u_123'], // the request's evaluated user/attribute map
['anonId' => $anonId], // optional opts: anonId, i18nProfile, baseUrl
)
. i18nScriptTag(
$clientKey, // PUBLIC client key — embedded in the page
'{{PROFILE}}', // locale profile to load (e.g. en:prod)
);i18n / render
The PHP server SDK has no t() — labels render in the browser via the client
SDK. After the loader tag (see setup) is in the <head>, render in the browser:
// browser, @shipeasy/sdk/client
import { t } from "@shipeasy/sdk/client";
element.textContent = t("checkout.cta"); // resolves from the {{PROFILE}} profileops
ops / see
Report a caught, handled error (or a non-exception "violation") to Shipeasy with
see() — fire-and-forget, never re-throws. Package-level, so it reports against
the SDK from Shipeasy\configure(). Assumes Shipeasy\configure() ran at startup
— see Installation.
Report a handled exception
use function Shipeasy\see;
try {
charge($order);
} catch (\Throwable $e) {
// ->causesThe($subject) what the error affects (e.g. "checkout"; default "app")
// ->to($outcome) the terminal — what you do about it; builds + fires once
see($e)->causesThe('checkout')->to('use the backup processor');
fallbackCharge($order);
}Attach context with ->extras(...)
use function Shipeasy\see;
try {
charge($order);
} catch (\Throwable $e) {
// ->extras($array) structured fields attached to the report (local-only debug)
see($e)->causesThe('checkout')->extras(['order_id' => $oid])->to('use cached prices');
}Report a non-exception violation
use function Shipeasy\seeViolation;
// a bad state that isn't an exception — the name is a STABLE fingerprint; put
// variable data in ->extras(), never the name. ->to() is the terminal.
seeViolation('missing_invoice')->causesThe('billing')->to('skip the dunning email');Mark an expected exception — report NOTHING
use function Shipeasy\controlFlowException;
try {
parse($token);
} catch (\Throwable $e) {
// transmits nothing; ->because(...) / ->extras() are local-debug only
controlFlowException($e)->because('end of stream is expected');
}Admin API client (optional) — `Shipeasy\Admin`
The base SDK evaluates flags, configs, and experiments (Shipeasy\configure() + new Shipeasy\Client($user)). The Admin API client is a separate, optional…
Agent skill
Installable LLM skill for the PHP SDK (configure() + Client(user), evaluate, experiment + track, testing).