configcat/configcat-client
ConfigCat PHP SDK client for feature flags and remote configuration. Fetch typed setting values from ConfigCat using your SDK key, with targeting by user attributes (region, email, custom). Supports PHP 8.1+ and integrates via Composer.
Installation
composer require configcat/configcat-client
Ensure your composer.json meets PHP 8.1+ requirements.
Retrieve SDK Key Grab your SDK key from ConfigCat Dashboard.
Initialize Client
$client = new \ConfigCat\ConfigCatClient('YOUR_SDK_KEY');
First Feature Flag Check
$isFeatureEnabled = $client->getValue('feature_flag_key', false);
if ($isFeatureEnabled) {
// New logic
}
ConfigCatClient Class – Core methods (getValue(), getAllValues(), forceRefresh()).// In a controller/service
public function toggleFeature(Request $request) {
$client = app(ConfigCatClient::class);
$isEnabled = $client->getValue('new_ui_enabled', false);
return $isEnabled ? view('new-ui') : view('old-ui');
}
// Create a user object (mandatory: identifier)
$user = new \ConfigCat\User($request->user()->id, [
'email' => $request->user()->email,
'country' => $request->ip()->country(),
]);
// Fetch flag with targeting
$isBetaFeature = $client->getValue('beta_feature', false, $user);
// Configure cache (e.g., Redis)
$client = new \ConfigCat\ConfigCatClient('SDK_KEY', [
\ConfigCat\ClientOptions::CACHE => new \ConfigCat\Cache\RedisCache(
new \Redis(),
'configcat'
),
\ConfigCat\ClientOptions::POLLING_INTERVAL => 60, // Refresh every 60s
]);
// Subscribe to config changes
$client->hooks()->onConfigChanged(function ($flags) {
\Log::info('ConfigCat flags updated', ['flags' => $flags]);
});
// Handle evaluation details
$client->hooks()->onFlagEvaluated(function ($details) {
\Log::debug('Flag evaluated', [
'key' => $details->getKey(),
'value' => $details->getValue(),
'reason' => $details->getReason(),
]);
});
// Force offline (cache-only)
$client->setOffline();
// Re-enable online mode
$client->setOnline();
// Get all flag values at once
$allFlags = $client->getAllValues($user);
$isFeatureA = $allFlags['feature_a'] ?? false;
// In AppServiceProvider@boot()
$this->app->singleton(ConfigCatClient::class, function ($app) {
return new \ConfigCat\ConfigCatClient(config('configcat.sdk_key'), [
\ConfigCat\ClientOptions::CACHE => new \ConfigCat\Cache\ArrayCache(),
]);
});
// config/configcat.php
return [
'sdk_key' => env('CONFIGCAT_SDK_KEY'),
'polling_interval' => env('CONFIGCAT_POLLING_INTERVAL', 60),
'cache' => env('CONFIGCAT_CACHE', 'array'), // 'array', 'redis', etc.
];
// app/Http/Middleware/FeatureGate.php
public function handle($request, Closure $next) {
$client = app(ConfigCatClient::class);
if (!$client->getValue('api_v2_enabled', false)) {
abort(503, 'API v2 is disabled.');
}
return $next($request);
}
Cache Invalidation Delays
POLLING_INTERVAL seconds to propagate.forceRefresh() to manually trigger a sync:
$client->forceRefresh();
User Object Requirements
User object must have a unique identifier. Missing or duplicate IDs break targeting.User::create($id, ['custom' => 'attributes']) for clarity.Offline Mode Pitfalls
getLastFetchTime() to verify cache freshness.Logging Overhead
WARNING level). Enable DEBUG only for troubleshooting:
$client = new \ConfigCat\ConfigCatClient('SDK_KEY', [
\ConfigCat\ClientOptions::LOG_LEVEL => \ConfigCat\Log\LogLevel::DEBUG,
]);
Guzzle Deprecation
REQUEST_OPTIONS) are deprecated. Use FetchClientInterface for custom HTTP clients:
$client = new \ConfigCat\ConfigCatClient('SDK_KEY', [
\ConfigCat\ClientOptions::FETCH_CLIENT => \ConfigCat\Http\GuzzleFetchClient::create([
\GuzzleHttp\RequestOptions::TIMEOUT => 5,
]),
]);
Evaluation Details
Use getValueDetails() to debug why a flag returned a specific value:
$details = $client->getValueDetails('flag_key', false, $user);
\Log::debug('Evaluation reason:', [
'reason' => $details->getReason(),
'matched_rule' => $details->getMatchedTargetingRule(),
]);
Cache Inspection Check cached flags with:
$client->getAllKeys(); // List all cached flag keys
$client->getLastFetchTime(); // Unix timestamp of last fetch
Network Issues
DEBUG logging to catch HTTP errors.try {
$client->forceRefresh();
} catch (\Exception $e) {
\Log::error('ConfigCat refresh failed', ['error' => $e->getMessage()]);
}
Custom Cache Backends
Implement \ConfigCat\Cache\CacheInterface for Redis, DynamoDB, etc.:
class RedisCache implements \ConfigCat\Cache\CacheInterface {
public function get(string $key): ?string { /* ... */ }
public function set(string $key, string $value): void { /* ... */ }
public function delete(string $key): void { /* ... */ }
}
Custom HTTP Clients Replace Guzzle with Psr-18 compliant clients (e.g., Symfony HTTP Client):
use Symfony\Contracts\HttpClient\HttpClientInterface;
class SymfonyFetchClient implements \ConfigCat\Http\FetchClientInterface {
public function __construct(private HttpClientInterface $client) {}
public function getClient(): \Psr\Http\Client\ClientInterface {
return new class($this->client) implements \Psr\Http\Client\ClientInterface {
// Adapt Symfony client to Psr-18
};
}
public function createRequest(string $method, string $uri): \Psr\Http\Message\RequestInterface {
// Adapt Symfony request to Psr-7
}
}
Flag Overrides Override flags locally (e.g., for testing):
$client = new \ConfigCat\ConfigCatClient('SDK_KEY', [
\ConfigCat\ClientOptions::FLAG_OVERRIDES => [
'debug_mode' => true, // Override 'debug_mode' flag
],
]);
Bulk Evaluation
Use getAllValues() instead of multiple getValue() calls to reduce network overhead.
Cache Tuning
POLLING_INTERVAL to balance freshness vs. load (e.g., 60 seconds for most apps).Offline Mode Enable offline mode during deployments to avoid race conditions:
if (app()->environment('deploying')) {
$client->setOffline();
}
How can I help you explore Laravel packages today?