PHPackages                             simplestats-io/php-client - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. simplestats-io/php-client

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

simplestats-io/php-client
=========================

Plain PHP client for SimpleStats analytics. Works with any PHP application.

10[2 PRs](https://github.com/simplestats-io/php-client/pulls)PHPCI passing

Since Mar 10Pushed 1mo agoCompare

[ Source](https://github.com/simplestats-io/php-client)[ Packagist](https://packagist.org/packages/simplestats-io/php-client)[ RSS](/packages/simplestats-io-php-client/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)DependenciesVersions (2)Used By (0)

PHP Client for SimpleStats.io
=============================

[](#php-client-for-simplestatsio)

[![Latest Version on Packagist](https://camo.githubusercontent.com/3dfd16faf486ac554c372277e79802a95af6307ddf92bb4d685dcbff67253b42/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73696d706c6573746174732d696f2f7068702d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/simplestats-io/php-client)[![Tests](https://github.com/simplestats-io/php-client/actions/workflows/run-tests.yml/badge.svg?branch=main)](https://github.com/simplestats-io/php-client/actions/workflows/run-tests.yml)[![Check & fix styling](https://github.com/simplestats-io/php-client/actions/workflows/fix-php-code-style-issues.yml/badge.svg?branch=main)](https://github.com/simplestats-io/php-client/actions/workflows/fix-php-code-style-issues.yml)[![License](https://camo.githubusercontent.com/3e5c81e24ffc9cba7136cc9ecfe0ac9dd309badcdfbf4ac187b926907da651c8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f73696d706c6573746174732d696f2f7068702d636c69656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/simplestats-io/php-client)

This is the official plain PHP client to send tracking data to . It works with any PHP 8.2+ application, no framework required.

For Laravel applications, use the dedicated [Laravel Client](https://github.com/simplestats-io/laravel-client) instead, which provides automatic middleware, observers, and queue integration.

Introduction
------------

[](#introduction)

***SimpleStats*** is a streamlined analytics tool that goes beyond simple page views. It offers **precise insights** into user origins and behaviors through server-side tracking. With default tracking and filtering via [UTM](https://en.wikipedia.org/wiki/UTM_parameters) codes, you gain detailed analysis of **marketing** campaigns, identifying which efforts drive **revenue**. Effortlessly evaluate campaign **ROI**, discover cost-effective user acquisition channels, and pinpoint the most effective performance channels. *SimpleStats* ensures full **GDPR compliance** and is unaffected by ad blockers since all tracking occurs server-side.

[![screenshot](https://camo.githubusercontent.com/6ceccc3ebb9862cafd664150e82380869bc27ae07fd11cb69c61e53e98d18603/68747470733a2f2f73696d706c6573746174732e696f2f696d616765732f73637265656e73686f742e706e67)](https://camo.githubusercontent.com/6ceccc3ebb9862cafd664150e82380869bc27ae07fd11cb69c61e53e98d18603/68747470733a2f2f73696d706c6573746174732e696f2f696d616765732f73637265656e73686f742e706e67)

Installation
------------

[](#installation)

```
composer require simplestats-io/php-client
```

Quick Start
-----------

[](#quick-start)

```
use SimpleStatsIo\PhpClient\SimplestatsClient;
use SimpleStatsIo\PhpClient\TrackingData;
use SimpleStatsIo\PhpClient\VisitorHashGenerator;

$client = new SimplestatsClient([
    'api_token' => 'your-api-token',
]);

// Generate a GDPR-compliant visitor hash
$visitorHash = VisitorHashGenerator::generate(
    ip: $_SERVER['REMOTE_ADDR'],
    userAgent: $_SERVER['HTTP_USER_AGENT'],
    secretKey: 'your-secret-key'
);

// Auto-extract tracking data from the current request
$trackingData = TrackingData::fromGlobals(appUrl: 'https://yourapp.com');

// Track the visitor
$client->trackVisitor($visitorHash, $trackingData);
```

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

[](#configuration)

Pass a configuration array when creating the client:

```
$client = new SimplestatsClient([
    'api_token'   => 'your-api-token',             // Required
    'api_url'     => 'https://simplestats.io/api/v1/', // Optional (default: SaaS URL)
    'timeout'     => 5,                             // Optional, seconds (default: 5)
    'max_retries' => 3,                             // Optional (default: 3)
    'enabled'     => true,                          // Optional (default: true)
]);
```

OptionTypeDefaultDescription`api_token`string(required)Your project API token from SimpleStats`api_url`string`https://simplestats.io/api/v1/`API base URL (change for self-hosted)`timeout`int`5`HTTP request timeout in seconds`max_retries`int`3`Number of retries on transient failures`enabled`bool`true`Set to `false` to disable all trackingWhen tracking is disabled, all methods return an empty array without making any HTTP requests.

Usage
-----

[](#usage)

### Tracking Visitors

[](#tracking-visitors)

Track anonymous visitors with optional UTM parameters and metadata:

```
$client->trackVisitor(
    visitorHash: $visitorHash,
    trackingData: $trackingData,
    time: new DateTimeImmutable() // optional, defaults to now
);
```

### Tracking User Registrations

[](#tracking-user-registrations)

```
$client->trackUser(
    id: $user->id,
    registeredAt: new DateTimeImmutable($user->created_at),
    trackingData: $trackingData, // optional
    addLogin: true               // optional, also track a login event
);
```

### Tracking Logins

[](#tracking-logins)

```
$client->trackLogin(
    userId: $user->id,
    userRegisteredAt: new DateTimeImmutable($user->created_at),
    ip: $_SERVER['REMOTE_ADDR'],       // optional
    userAgent: $_SERVER['HTTP_USER_AGENT'], // optional
    time: new DateTimeImmutable()       // optional, defaults to now
);
```

### Tracking Payments

[](#tracking-payments)

Amounts must be in **cents** (e.g., 2000 = $20.00). Currency must be [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (EUR, USD, GBP, etc.).

Associate a payment with either a user or a visitor:

```
// Payment linked to a registered user
$client->trackPayment(
    id: $payment->id,
    gross: 2000,
    net: 1680,
    currency: 'EUR',
    time: new DateTimeImmutable($payment->created_at),
    userId: $user->id,
    userRegisteredAt: new DateTimeImmutable($user->created_at)
);

// Payment linked to an anonymous visitor (e.g., guest checkout)
$client->trackPayment(
    id: $payment->id,
    gross: 2000,
    net: 1680,
    currency: 'EUR',
    time: new DateTimeImmutable($payment->created_at),
    visitorHash: $visitorHash
);
```

### Tracking Custom Events

[](#tracking-custom-events)

```
$client->trackCustomEvent(
    id: 'evt_123',
    name: 'subscription_upgraded',
    time: new DateTimeImmutable(),  // optional, defaults to now
    userId: $user->id,              // optional
    userRegisteredAt: new DateTimeImmutable($user->created_at) // optional
);
```

Tracking Data
-------------

[](#tracking-data)

The `TrackingData` class holds visitor metadata (IP, user agent, UTM parameters, referer, page entry).

### Auto-extract from the current request

[](#auto-extract-from-the-current-request)

```
$trackingData = TrackingData::fromGlobals(appUrl: 'https://yourapp.com');
```

This automatically extracts:

- **IP address** from proxy-aware headers (Cloudflare, Akamai, X-Forwarded-For, X-Real-IP, REMOTE\_ADDR)
- **User agent** from the request
- **UTM parameters** from query string (`utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `ref`, `referer`, `referrer`, `adGroup`, `adGroupId`)
- **Referer** domain from the HTTP referer header (self-referrals excluded via `appUrl`)
- **Page entry** path (URI without query string)

### Build manually

[](#build-manually)

```
$trackingData = new TrackingData(
    ip: '203.0.113.50',
    userAgent: 'Mozilla/5.0 ...',
    referer: 'google.com',
    source: 'google',
    medium: 'cpc',
    campaign: 'spring_sale',
    term: 'analytics tool',
    content: 'banner_ad',
    pageEntry: '/pricing',
);
```

Visitor Hash Generator
----------------------

[](#visitor-hash-generator)

Generate GDPR-compliant anonymized visitor identifiers. The hash rotates daily to prevent long-term tracking.

```
use SimpleStatsIo\PhpClient\VisitorHashGenerator;

$hash = VisitorHashGenerator::generate(
    ip: $_SERVER['REMOTE_ADDR'],
    userAgent: $_SERVER['HTTP_USER_AGENT'],
    secretKey: 'your-secret-key',
    date: '2024-06-15' // optional, defaults to today
);
```

The generator creates a SHA-256 hash from IP + User-Agent + date + secret key, truncated to 32 characters. The daily date rotation ensures hashes are not persistent across days, keeping visitor tracking fully anonymous.

Error Handling
--------------

[](#error-handling)

The client throws specific exceptions you can catch:

```
use SimpleStatsIo\PhpClient\Exceptions\ConfigurationException;
use SimpleStatsIo\PhpClient\Exceptions\ApiRequestFailed;

try {
    $client->trackVisitor($visitorHash, $trackingData);
} catch (ConfigurationException $e) {
    // Invalid configuration (e.g., missing api_token)
} catch (ApiRequestFailed $e) {
    // API request failed after retries
    $e->getMessage();    // Error description
    $e->statusCode;      // HTTP status code
    $e->responseBody;    // Raw response body
}
```

The HTTP client automatically retries on transient failures (connection errors, 429, 5xx) with exponential backoff.

Performance: Non-Blocking Tracking
----------------------------------

[](#performance-non-blocking-tracking)

By default, all tracking calls are **synchronous** and block the current request. In production, you should avoid adding latency to your user-facing responses. Here are a few strategies:

- **`fastcgi_finish_request()`** (recommended for PHP-FPM): Send the response to the client first, then run tracking calls afterwards. Zero dependencies, works out of the box with PHP-FPM.
- **File/SQLite queue with cron**: Write tracking data to a local file or SQLite database, then process it in the background with a cron job. Most reliable approach, but requires a worker setup.
- **Guzzle async requests**: Use Guzzle's `requestAsync()` combined with `fastcgi_finish_request()` to run multiple tracking calls in parallel after the response is sent.

```
// Example: fastcgi_finish_request()
echo $responseBody;
fastcgi_finish_request(); // Response is delivered to the client

$client->trackVisitor($visitorHash, $trackingData); // Runs in the background
```

Testing
-------

[](#testing)

```
composer test
```

Documentation
-------------

[](#documentation)

- [Official SimpleStats.io Documentation](https://simplestats.io/docs)
- [API Documentation](https://simplestats.io/docs/api-documentation.html)

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Zacharias Creutznacher](https://github.com/sairahcaz)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance59

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 90.9% 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://www.gravatar.com/avatar/cf347b32c0d1fceabbcbce7626ad662faa34738396fd9f774231d55370823713?d=identicon)[Sairahcaz](/maintainers/Sairahcaz)

---

Top Contributors

[![Sairahcaz](https://avatars.githubusercontent.com/u/7384870?v=4)](https://github.com/Sairahcaz "Sairahcaz (10 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

### Embed Badge

![Health badge](/badges/simplestats-io-php-client/health.svg)

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

PHPackages © 2026

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