PHPackages                             alitycs/alitycs-sdk-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. alitycs/alitycs-sdk-php

ActiveLibrary

alitycs/alitycs-sdk-php
=======================

Alitycs Analytics SDK for PHP — server-side event tracking with batching, sessions, and retry.

00PHPCI passing

Since Aug 28Pushed todayCompare

[ Source](https://github.com/alitycs/alitycs-sdk-php)[ Packagist](https://packagist.org/packages/alitycs/alitycs-sdk-php)[ RSS](/packages/alitycs-alitycs-sdk-php/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

alitycs-sdk-php
===============

[](#alitycs-sdk-php)

Alitycs Analytics SDK for PHP server applications. Events are batched and delivered to the Alitycs ingest endpoint over HTTPS, validating against the shared event contract (`specs/event-schema.json` v0.4.0).

Requires PHP &gt;= 8.1 with `ext-curl` and `ext-json`. No other runtime dependencies.

```
composer require alitycs/alitycs-sdk-php
```

Quickstart
----------

[](#quickstart)

```
use Alitycs\Client;
use Alitycs\RevenuePayload;

$alitycs = new Client('pk_live_…', [
    'endpoint' => 'https://api.alitycs.com/events',
    'flushSize' => 20,
]);

$alitycs->identify('usr_1842', ['plan' => 'pro']);
$alitycs->track('signup_completed', ['plan' => 'free']);
$alitycs->page('Dashboard');
$alitycs->captureError('checkout_failed', ['code' => 'E_CARD']);
$alitycs->trackRevenue(RevenuePayload::transaction('fact_1', '19.99', 'USD'));
$alitycs->setGlobalProperties(['suite' => 'checkout']);
$alitycs->reset();          // rotates session + anonymous id, clears the user

$alitycs->shutdown();       // or let script shutdown deliver the remainder
```

There is no background flusher
------------------------------

[](#there-is-no-background-flusher)

**PHP has no background threads**, so this SDK has no timer-based flush. Queued events are delivered by exactly three triggers:

1. **Queue depth** — when the queue reaches `flushSize`.
2. **Explicit `flush()`** — sends everything currently queued as one batch.
3. **Script shutdown** — via `register_shutdown_function()`, so a request that ends without an explicit flush still delivers.

`shutdown()` resolves ownership without silently losing queued events; it is safe to call more than once. After it returns, every enqueued event has been sent, durably retained, or permanently dropped and counted under the retry policy below. Events enqueued after `shutdown()` are ignored (logged in debug mode), because there is nothing left to deliver them.

`flushInterval` exists for API parity but is **opportunistic**: it is never a timer. It is checked only while events keep arriving — each enqueue compares elapsed wall time against the interval and flushes if it has elapsed. A request whose final event arrives before the interval does will not be sent until `flush()`/`shutdown()` or the next event. Set it to `0` to disable the check entirely.

In long-running processes (workers, daemons), call `flush()` on your own cadence — do not rely on request lifecycle hooks that never fire.

Long-running workers (Octane, Swoole, RoadRunner)
-------------------------------------------------

[](#long-running-workers-octane-swoole-roadrunner)

A single `Client` instance kept alive across many logical requests carries state: `identify()`'s user id, `setGlobalProperties()`, and the session/anonymous ids. Without a per-request reset that state leaks into the next request's events — event A's user gets credited for request B's actions.

Call `resetForRequest()` at the top of every logical request, before tracking anything:

```
// e.g. Laravel Octane: in a middleware or the ListenForEventsTick listener
$app->middleware(function ($request, $next) use ($alitycs) {
    $alitycs->resetForRequest();   // clears user id, global properties, session identity
    return $next($request);
});
```

When logical requests can overlap on one client, pass a named per-call `userId` instead of mutating shared identity. The override is captured only for that event:

```
$alitycs->track('checkout_started', userId: $request->userId);
$alitycs->captureError('checkout_failed', ['code' => 'E_CARD'], userId: $request->userId);
```

The same optional argument is available on `trackRevenue()` and `page()`. Omitting it uses the ambient identity from `identify()`; passing a blank string explicitly suppresses that ambient identity for the individual event.

Queued but unsent events are **not** dropped by `resetForRequest()`; flush beforehand if they should be delivered before the identities change. For Swoole coroutine workers, prefer per-call `userId` values; resetting shared ambient state while requests overlap is not safe.

Configuration
-------------

[](#configuration)

OptionDefaultMeaning`endpoint``https://api.alitycs.com/events`Ingest URL`flushSize``25`Queue depth that triggers a send`flushInterval``10.0`Opportunistic seconds between flushes; `0` disables`maxQueueSize``1000`Buffered events before new arrivals are dropped`maxRetries``3`Attempts after the first (5xx / 429 / network errors only)`timeoutMs``10000`Per-request HTTP timeout`sessionTimeout``1800000`Inactivity (ms) before the session id rotates`debug``false`Log diagnostics to stderr under `[Alitycs]``batching``true`When `false`, every event is its own single-event batch`persistencePath``null`Optional exact in-flight batch WAL path for restart recoveryUnknown option names throw — a typo fails loudly instead of running on defaults.

Retry policy
------------

[](#retry-policy)

Batches are retried with exponential backoff (1s, 2s, 4s … capped at 10s) on `5xx`, `429`, and network errors, up to `maxRetries` times. Any other `4xx` is permanent and is never retried. A server `Retry-After` value replaces the generated delay and uses a separate 60s safety bound rather than the 10s client-backoff cap. Delivery failures are logged, never thrown — a dead endpoint cannot fatal your application. Without persistence, an exhausted transient batch is lost. With `persistencePath`, the exact serialized batch is atomically retained. A later `flush()`/`shutdown()` replays it byte-identically after any remaining `Retry-After` pause has elapsed; it returns promptly while a pause is still active. Terminal responses acknowledge and remove the record. The WAL also accepts queued events during a blocked shutdown and is capped at `maxQueueSize` retained events. Configure one process owner per path. After a fork, the child detaches from the inherited parent WAL; create a fresh client with a child-specific `persistencePath` when child delivery must also be durable.

Revenue
-------

[](#revenue)

`trackRevenue()` requires a secret key with `revenue:write`. Payloads are built through named constructors matching the wire contract's three variants: `RevenuePayload::transaction(...)`, `::mrrSnapshot(...)`, and `::mrrBaselineComplete(...)`. Invalid combinations of fields for a variant cannot be constructed.

Not in scope
------------

[](#not-in-scope)

Feature flags, session recording, group analytics, and log ingestion are not Alitycs capabilities and are deliberately absent here. The PHP SDK is server-class: it has no autocapture — call `page()` explicitly.

Development
-----------

[](#development)

```
composer install
vendor/bin/phpunit                       # unit + integration suite
composer run test:coverage               # suite + coverage gate (lines >= 90%, methods >= 85%)
composer run conformance                 # conformance app against $CAPTURE_URL
```

###  Health Score

20

—

LowBetter than 12% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/58190305?v=4)[bulanovdm](/maintainers/bulanovdm)[@bulanovdm](https://github.com/bulanovdm)

---

Top Contributors

[![bulanovdm](https://avatars.githubusercontent.com/u/58190305?v=4)](https://github.com/bulanovdm "bulanovdm (5 commits)")

### Embed Badge

![Health badge](/badges/alitycs-alitycs-sdk-php/health.svg)

```
[![Health](https://phpackages.com/badges/alitycs-alitycs-sdk-php/health.svg)](https://phpackages.com/packages/alitycs-alitycs-sdk-php)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
