togglebox / sdk
PHP SDK for ToggleBox - Remote Config, Feature Flags, and A/B Experiments
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- psr/simple-cache: ^3.0
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2026-03-29 01:14:12 UTC
README
Official PHP SDK for ToggleBox - Remote Config, Feature Flags, and A/B Experiments.
Installation
composer require togglebox/sdk
Quick Start
use ToggleBox\ToggleBoxClient; use ToggleBox\Types\ClientOptions; use ToggleBox\Types\FlagContext; use ToggleBox\Types\ExperimentContext; // Initialize the client $client = new ToggleBoxClient(new ClientOptions( platform: 'web', environment: 'production', apiUrl: 'https://api.yourdomain.com', // Self-hosted // OR for cloud: // tenantSubdomain: 'your-tenant', apiKey: 'your-api-key', // Optional for self-hosted ));
Tier 1: Remote Configs
Remote configs provide the same value to everyone - perfect for feature toggles, API URLs, and app settings.
// Get a single config value with type-safe default $apiUrl = $client->getConfigValue('api_url', 'https://default.api.com'); $maxRetries = $client->getConfigValue('max_retries', 3); // Get all active config parameters as key-value array $allConfigs = $client->getAllConfigs(); // Returns: ['api_url' => 'https://...', 'max_retries' => 5, ...]
Tier 2: Feature Flags (2-Value Model)
Feature flags support targeting by country and language with a simple 2-value model (A/B).
$context = new FlagContext( userId: 'user-123', country: 'US', language: 'en', ); // Get flag result with full details $result = $client->getFlag('new-checkout-ui', $context); echo $result->value; // The actual value (valueA or valueB) echo $result->servedValue; // 'A' or 'B' echo $result->reason; // 'targeting_match', 'rollout', etc. // Simple boolean check if ($client->isFlagEnabled('dark-mode', $context)) { enableDarkMode(); } // Get flag metadata without evaluation $flagInfo = $client->getFlagInfo('dark-mode'); if ($flagInfo !== null) { echo $flagInfo->flagKey; // 'dark-mode' echo $flagInfo->name; // 'Dark Mode' echo $flagInfo->enabled; // true/false echo $flagInfo->valueA; // Value A echo $flagInfo->valueB; // Value B }
Tier 3: A/B Experiments
Full multi-variant experiments with traffic allocation and conversion tracking.
$context = new ExperimentContext( userId: 'user-123', country: 'US', language: 'en', ); // Get the user's assigned variation $variant = $client->getVariant('checkout-redesign', $context); if ($variant !== null) { echo $variant->variationKey; // 'control', 'variant_1', etc. echo $variant->variationName; // 'Control', 'Variant 1', etc. echo $variant->value; // The variation's value (JSON or string) echo $variant->isControl; // true/false } // Track a conversion use ToggleBox\Types\ConversionData; $client->trackConversion('checkout-redesign', $context, new ConversionData( metricName: 'purchase', value: 99.99, // Optional: for sum/average metrics )); // Get experiment metadata without assignment $experimentInfo = $client->getExperimentInfo('checkout-redesign'); if ($experimentInfo !== null) { echo $experimentInfo->experimentKey; // 'checkout-redesign' echo $experimentInfo->name; // 'Checkout Redesign' echo $experimentInfo->status; // 'running', 'draft', 'completed' print_r($experimentInfo->variations); // Array of variations } // Flush stats to server (call at end of request) $client->flushStats();
Caching
By default, the SDK uses an in-memory array cache that persists for the lifetime of the request. For better performance across requests, provide a PSR-16 compatible cache:
use ToggleBox\Cache\PsrCacheAdapter; // Using Symfony Cache $symfonyCache = new \Symfony\Component\Cache\Psr16Cache( new \Symfony\Component\Cache\Adapter\RedisAdapter($redis) ); $client = new ToggleBoxClient( new ClientOptions( platform: 'web', environment: 'production', apiUrl: 'https://api.yourdomain.com', cache: new CacheOptions( enabled: true, ttl: 300, // 5 minutes ), ), new PsrCacheAdapter($symfonyCache), );
Manual Cache Refresh
// Force refresh all cached data $client->refresh(); // Clear all caches $client->clearCache();
Health Check
// Check API connectivity try { $health = $client->checkConnection(); echo $health['status']; // 'ok' } catch (\ToggleBox\Exceptions\ToggleBoxException $e) { // API is unreachable log_error('ToggleBox API is down: ' . $e->getMessage()); }
Error Handling
use ToggleBox\Exceptions\ToggleBoxException; use ToggleBox\Exceptions\NetworkException; use ToggleBox\Exceptions\ConfigurationException; try { $variant = $client->getVariant('my-experiment', $context); } catch (NetworkException $e) { // API request failed log_error('ToggleBox API error: ' . $e->getMessage()); } catch (ToggleBoxException $e) { // Other SDK errors (e.g., experiment not found) log_error('ToggleBox error: ' . $e->getMessage()); }
Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
platform |
string | Yes | Platform name (e.g., 'web', 'mobile') |
environment |
string | Yes | Environment name (e.g., 'production', 'staging') |
apiUrl |
string | * | API base URL (for self-hosted) |
tenantSubdomain |
string | * | Tenant subdomain (for cloud) |
apiKey |
string | No | API key for authentication |
cache |
CacheOptions | No | Cache configuration |
configVersion |
string | No | Default config version ('stable', 'latest', or specific) |
* Either apiUrl or tenantSubdomain is required, but not both.
Requirements
- PHP 8.1 or higher
- Guzzle HTTP client
License
MIT