PHP Client
The SimpleStats PHP client lets you add server-side analytics to any PHP 8.2+ application. No framework required. If you're using Symfony, Slim, WordPress, or plain PHP, this is the package for you.
TIP
Using Laravel? The Laravel client package provides automatic tracking via middleware, Eloquent observers, and event listeners. You don't need this package.
Requirements
- PHP 8.2+
- Guzzle 7.5+
Installation
composer require simplestats-io/php-clientConfiguration
Create a client instance with your API token:
use SimpleStatsIo\PhpClient\SimplestatsClient;
$client = new SimplestatsClient([
'api_token' => 'your-api-token',
]);Available config options:
$client = new SimplestatsClient([
'api_token' => 'your-api-token', // required
'api_url' => 'https://simplestats.io/api/v1/', // default
'timeout' => 5, // seconds, default 5
'max_retries' => 3, // default 3
'enabled' => true, // set false to disable tracking
]);Visitor Tracking
Generating a Visitor Hash
SimpleStats identifies visitors with a GDPR-compliant hash that rotates daily. You generate it from the visitor's IP, user agent, and a secret key:
use SimpleStatsIo\PhpClient\VisitorHashGenerator;
$visitorHash = VisitorHashGenerator::generate(
ip: $_SERVER['REMOTE_ADDR'],
userAgent: $_SERVER['HTTP_USER_AGENT'],
secretKey: 'your-secret-key',
);The same visitor gets the same hash within a day, but a different hash the next day. IPs and user agents are never sent to the API.
Extracting Tracking Data
The TrackingData class collects UTM parameters, referrer, IP, user agent, and entry page from the current request:
use SimpleStatsIo\PhpClient\TrackingData;
$trackingData = TrackingData::fromGlobals(appUrl: 'https://yourapp.com');This automatically extracts:
- UTM parameters (
utm_source,utm_medium,utm_campaign,utm_term,utm_content) - Alternative source params (
ref,referer,referrer) - HTTP Referer header (excluding self-referrals)
- Client IP (with Cloudflare/proxy header support)
- Entry page path
You can also build it manually:
$trackingData = new TrackingData(
ip: '203.0.113.42',
userAgent: 'Mozilla/5.0 ...',
source: 'google',
medium: 'cpc',
campaign: 'spring-sale',
);Sending the Visitor Event
$client->trackVisitor($visitorHash, $trackingData);User Registration Tracking
Track when a user registers. The $id should be your application's user ID:
$client->trackUser(
id: $user->id,
registeredAt: $user->createdAt,
trackingData: $trackingData,
);If you want to record a login event at the same time (e.g. auto-login after registration):
$client->trackUser(
id: $user->id,
registeredAt: $user->createdAt,
trackingData: $trackingData,
addLogin: true,
);Login Tracking
$client->trackLogin(
userId: $user->id,
userRegisteredAt: $user->createdAt,
ip: $_SERVER['REMOTE_ADDR'],
userAgent: $_SERVER['HTTP_USER_AGENT'],
);Payment Tracking
Amounts must be in cents (integer). Currency in ISO 4217 format:
$client->trackPayment(
id: $payment->id,
gross: 2000, // $20.00
net: 1800, // $18.00
currency: 'USD',
time: $payment->paidAt,
userId: $user->id,
userRegisteredAt: $user->createdAt,
);For guest checkouts without a user account, link the payment to a visitor hash instead:
$client->trackPayment(
id: $payment->id,
gross: 2000,
net: 1800,
currency: 'USD',
time: $payment->paidAt,
visitorHash: $visitorHash,
);Custom Event Tracking
Track any event that doesn't fit the standard lifecycle:
$client->trackCustomEvent(
id: 'evt_123',
name: 'plan_upgraded',
userId: $user->id,
userRegisteredAt: $user->createdAt,
);Non-Blocking Tracking
API calls are synchronous by default. To avoid slowing down your response, send the response to the client first and track afterwards:
// Send the response to the browser
fastcgi_finish_request();
// Now track (runs after the response is delivered)
$client->trackVisitor($visitorHash, $trackingData);If your application uses a queue system, dispatch the tracking call as a background job instead.
Error Handling
The client retries failed requests automatically (up to 3 times with exponential backoff) for connection errors, rate limits (HTTP 429), and server errors (HTTP 5xx).
If all retries fail, an ApiRequestFailed exception is thrown:
use SimpleStatsIo\PhpClient\Exceptions\ApiRequestFailed;
try {
$client->trackVisitor($visitorHash, $trackingData);
} catch (ApiRequestFailed $e) {
// $e->getMessage() contains status code and response body
error_log('SimpleStats tracking failed: ' . $e->getMessage());
}Self-Hosted
Point the client to your own SimpleStats instance:
$client = new SimplestatsClient([
'api_token' => 'your-api-token',
'api_url' => 'https://stats.yourdomain.com/api/v1/',
]);