PHPackages                             kilden/kilden-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. kilden/kilden-php

ActiveLibrary

kilden/kilden-php
=================

Kilden PHP SDK — server-side events, identity signing and feature flags. Zero dependencies, PHP 7.4+.

v0.1.0-alpha.5(1mo ago)0990↓71.1%1MITPHPPHP &gt;=7.4CI failing

Since Jul 14Pushed 1mo agoCompare

[ Source](https://github.com/kildenhq/kilden-sdk-php)[ Packagist](https://packagist.org/packages/kilden/kilden-php)[ Docs](https://kilden.io)[ RSS](/packages/kilden-kilden-php/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (2)Versions (8)Used By (1)

 [![Kilden PHP SDK](.github/assets/hero.png)](.github/assets/hero.png)

Kilden PHP SDK
==============

[](#kilden-php-sdk)

[![Packagist](https://camo.githubusercontent.com/f9b2e04af8fc26784ede4c7c1a9d207d0bde10e788c13e7f6264cf7ad9250dfc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b696c64656e2f6b696c64656e2d706870)](https://packagist.org/packages/kilden/kilden-php)[![ci](https://github.com/kildenhq/kilden-sdk-php/actions/workflows/ci.yml/badge.svg)](https://github.com/kildenhq/kilden-sdk-php/actions/workflows/ci.yml)[![license](https://camo.githubusercontent.com/40d6cd116f190c7bee460bd4d1d0f9db1f0767381c0feec6688ec1a77f1dcd7e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6b696c64656e68712f6b696c64656e2d73646b2d706870)](LICENSE)

Server-side PHP SDK for [Kilden](https://kilden.io), the open customer data platform: events, identity verification and feature flags from your backend. PHP 7.4+, zero dependencies — it runs on the shared hosting your WordPress client lives on and on your Laravel 13 app alike.

```
composer require kilden/kilden-php:@alpha
# (the @alpha flag goes away at 0.1.0)
```

```
$kilden = new Kilden\Client('sk_your_secret_key');

$kilden->track('user_42', 'order_completed', [
    'revenue' => 99.9,
    'currency' => 'CLP',
]);
```

That is a complete, working integration: events queue in memory and flush in batches (20 events or 10 seconds, whichever comes first), with gzip, retries with backoff, and a shutdown hook that delivers whatever is left after your response is sent — under FPM it runs after `fastcgi_finish_request()`, so telemetry never adds latency your user can feel.

**Use the secret key (`sk_`), never the public one.** Events sent with the secret key are `source=server`, `verified=true` — facts your campaigns and revenue reports can trust. The constructor rejects public (`wk_`) keys outright. Keep the secret key out of browsers, mobile apps, and frontend bundles of any kind.

Identity verification
---------------------

[](#identity-verification)

Anyone can open a browser console and send events as `user_id=ceo@corp` — unless you turn on identity verification. Your backend signs a short-lived token vouching for the logged-in user; Kilden's web SDK attaches it, and the platform marks those events verified. Signing is the part only your backend can do, and it is three lines:

```
$signer = new Kilden\IdentitySigner($_ENV['KILDEN_IDENTITY_SECRET'], ['kid' => 'k1']);

$token = $signer->sign($user->id, [
    'ttl'    => 3600,
    'traits' => ['plan' => $user->plan],   // signed traits override unsigned ones
]);
```

**Only sign a `sub` your backend authenticated.** Signing request input — `$signer->sign($_POST['user_id'])` — lets anyone impersonate anyone, with a "verified" stamp on top. Sign `$user->id` after your auth layer resolved it, never before.

Traits passed to `sign()` become *signed traits*: during enrichment they win over any unsigned traits the browser claims for the same event.

Feature flags
-------------

[](#feature-flags)

```
if ($kilden->isEnabled('new_checkout', 'user_42')) {
    // ...
}

$variant = $kilden->getFeatureFlag('pricing_test', 'user_42', [
    'person_properties' => ['plan' => 'pro'],  // evaluated server-side, this call only
    'default'           => false,              // returned if Kilden is unreachable
]);
```

`getFeatureFlag` returns `false`, `true`, or the variant key as a string. Evaluation is remote against `/decide` with a 30-second in-memory cache per `distinct_id`; calls with `person_properties` bypass the cache. When Kilden cannot answer within `timeout` (default 3s), you get your `default` back — one attempt, no retries, your request never blocks on a flag.

Batching, flush and shutdown
----------------------------

[](#batching-flush-and-shutdown)

Events do not hit the network on every `track()`. They queue in memory and flush when the queue reaches `flush_at` (default 20), when `flush_interval`elapses on a long-running process, or when you say so:

```
$kilden->flush();   // blocking: drain everything queued right now
$kilden->close();   // flush with a 10s deadline, then refuse further events
```

Call `close()` at the end of CLI scripts and workers. Under FPM you can skip it: a `register_shutdown_function` hook flushes after the response is handed off. If the process dies before any flush path runs (`kill -9`, fatal at the wrong instant), queued events are lost — that is the documented trade-off of in-memory batching; anything stricter needs a persistent queue on your side.

The queue is bounded (`max_queue_size`, default 10 000). When full, the newest event is dropped and counted; `$kilden->droppedCount()` tells you how many events were lost to a full queue, invalid input or exhausted retries.

Options
-------

[](#options)

```
$kilden = new Kilden\Client('sk_...', [
    'host'            => 'https://ingest.kilden.io',
    'flush_at'        => 20,
    'flush_interval'  => 10,
    'max_queue_size'  => 10000,
    'timeout'         => 3,
    'transport'       => null,     // autodetect: curl, then stream wrappers
    'debug'           => false,
    'enabled'         => true,     // false = full no-op for tests and local dev
]);
```

The constructor throws on misconfiguration (missing key, public key, no transport available) — fail at boot, not at 3am. After construction the SDK never throws: invalid input is dropped and logged, and delivery failures degrade to dropped batches, never to exceptions in your request path.

No `ext-curl`? The SDK falls back to stream wrappers automatically, and you can inject any `Kilden\Transport\Transport` implementation (that is how the WordPress plugin routes through `wp_remote_post()`).

Laravel
-------

[](#laravel)

The [`kilden/laravel`](packages/laravel) package wraps this SDK for Laravel 11–13: config file, `Kilden` facade, queued delivery, and the `POST /kilden/identity` endpoint the web SDK refreshes its tokens against.

```
// config/kilden.php via: php artisan vendor:publish --tag=kilden-config
Kilden::track($user->id, 'subscription_started', ['plan' => 'pro']);

// routes/web.php — one line, behind your auth middleware:
KildenRoutes::identity();
```

With `KILDEN_QUEUE=true`, event calls dispatch a Horizon/queue job instead of sending inline. `Kilden::fake()` gives you a spy with `assertTracked()` for your test suite.

Spec
----

[](#spec)

This SDK implements the [Kilden server SDK specification](https://github.com/kildenhq/kilden-sdk-spec)(spec version 0.1) and runs its frozen test vectors — including byte-exact identity token signatures — against the shared mock capture server in CI. Behavior changes land in the spec first, then here.

Community
---------

[](#community)

- [Documentation](https://kilden.io/docs)
- [Discussions](https://github.com/kildenhq/kilden-sdk-php/discussions)

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance91

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity24

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.

###  Release Activity

Cadence

Every ~0 days

Total

5

Last Release

45d ago

### Community

Maintainers

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

---

Top Contributors

[![gdespirito](https://avatars.githubusercontent.com/u/1103494?v=4)](https://github.com/gdespirito "gdespirito (44 commits)")

---

Tags

analyticscdpkildenlaravelphpsdkeventsanalyticsfeature-flagsCDPkilden

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[doctrine/event-manager

The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.

6.0k544.1M178](/packages/doctrine-event-manager)[psr/event-dispatcher

Standard interfaces for event handling.

2.3k702.7M1.7k](/packages/psr-event-dispatcher)[qodenl/laravel-posthog

Laravel implementation for Posthog

35121.6k](/packages/qodenl-laravel-posthog)[keen-io/keen-io-bundle

Symfony Bundle for Keen IO

17490.4k](/packages/keen-io-keen-io-bundle)[there4/php-analytics-event

Send Google Analytics events from PHP

2541.6k](/packages/there4-php-analytics-event)

PHPackages © 2026

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