contenzi / sdk-php
Contenzi SDK for PHP with OpenFeature
Requires
- ext-apcu: *
- ext-curl: *
- open-feature/sdk: ^2.0
This package is not auto-updated.
Last update: 2025-05-30 14:03:26 UTC
README
Installation
To use the Contenzi PHP SDK, install it using Composer:
composer require contenzi/sdk-php "v0.1.0-beta"
Setting Up the SDK
The SDK is based on OpenFeature and requires setting up a provider, evaluation context, and client. Follow these steps to configure it properly.
1. Generate a Targeting Key
Each user should have a unique targeting key stored in a cookie for consistent evaluations. If the cookie does not exist, generate a new targeting key and store it.
function generateTargetingKey() { return (string)rand(1, 10000); // Can also use a random UUID if preferred } // Check if the targeting key exists, otherwise generate and store it $targetingKey = isset($_COOKIE['exp_seed']) ? $_COOKIE['exp_seed'] : generateTargetingKey(); setcookie('exp_seed', $targetingKey, time() + (86400 * 365), "/"); // Store for 1 year
2. Initialize the SDK
Create an instance of ContenziProvider
, ensuring you pass both the App ID and the cache path as parameters.
The App ID can be found in the SDK configuration screen of the Contenzi app. The cache path needs to be shared
with the scheduled feature flag update job and must be writable by that job.
use Contenzi\Sdk\OpenFeature\ContenziProvider; use OpenFeature\implementation\flags\EvaluationContext; use OpenFeature\OpenFeatureAPI; $api = OpenFeatureAPI::getInstance(); $api->setProvider(new ContenziProvider("35bc2c6d-036d-4142-807c-e8e281fdfc25", "/opt/contenzi/php-sdk/flags")); $api->setEvaluationContext(new EvaluationContext($targetingKey)); $openFeatureClient = $api->getClient();
3. Retrieve Feature Flags
Retrieve the flag values using standard OpenFeature Evaluation API
// Retrieve feature flag values $value = $openFeatureClient->getStringValue('example', "x"); echo "example flag: " . $value;
Setting Up the Settings Fetcher Cron Job
The SDK requires periodic flag updates via the SettingsFetcher.php
script. This should be set up as a cron job running every minute.
Example Cron Job Setup
* * * * * /usr/local/bin/php /path/to/sdk/SettingsFetcher.php a12345.ctz-content.com 35bc2c6d-036d-4142-807c-e8e281fdfc25 /opt/contenzi/php-sdk/flags
Explanation of Parameters
- API endpoint, replace "a12345" with the correct account identifier
35bc2c6d-036d-4142-807c-e8e281fdfc25
→ Application ID (retrieved from the user interface)/opt/contenzi/php-sdk/flags
→ Path to store the cached flags (ensure this path is writable)
Note: Ensure that the path to SettingsFetcher.php
is correctly set based on your installation.
Important Considerations
- Writable Cache Directory: The flag storage path (
/opt/contenzi/php-sdk/flags
) must be writable by the PHP process. - Persistent User Identification: Store the generated
targetingKey
in a cookie to maintain consistent evaluations across sessions. - Experiment seed cookie: Ensure this cookie has a uniform random distribution for your visitors.
Example Code
The following code combines all the steps listed above:
use Contenzi\Sdk\OpenFeature\ContenziProvider; use OpenFeature\implementation\flags\EvaluationContext; use OpenFeature\OpenFeatureAPI; // Generate or retrieve a user-specific targeting key function generateTargetingKey() { return (string)rand(1, 10000); // Can also use UUID if preferred } $targetingKey = isset($_COOKIE['exp_seed']) ? $_COOKIE['exp_seed'] : generateTargetingKey(); setcookie('exp_seed', $targetingKey, time() + (86400 * 365), "/"); // Store for 1 year // Initialize the SDK $api = OpenFeatureAPI::getInstance(); $api->setProvider(new ContenziProvider("35bc2c6d-036d-4142-807c-e8e281fdfc25", "/opt/contenzi/php-sdk/flags")); $api->setEvaluationContext(new EvaluationContext($targetingKey)); $openFeatureClient = $api->getClient(); // Retrieve feature flag values $value = $openFeatureClient->getStringValue('example', "x"); echo "example flag: " . $value;
Handling Caching
Ensure the experiment cookie is not cached
If full page caching is used it is important to ensure the cookie used to set the experiment seed is not cached since this would prevent the users from being randomly distributed among the test groups. To solve this, set the cookie at the edge.
Varnish example
import std; sub vcl_deliver { if (!req.http.Cookie ~ "exp_seed") { set resp.http.Set-Cookie = "exp_seed=" + std.random(0, 10000) + "; Path=/; Max-Age=31536000"; } }
Nginx example
set $new_exp_seed $request_id; if ($cookie_exp_seed) { set $new_exp_seed $cookie_exp_seed; } add_header Set-Cookie "exp_seed=$new_exp_seed; Path=/; Max-Age=31536000";
Note: This will generate a long random ID, alternatively generate a small random number between 1 and 10,000 using Nginx Lua support for better user privacy.
How to maximize caching with experiments
Pages with experiments or personalisation will have to vary per user, so full page caching can't be applied. To enhance performance of these pages, choose between the following methods:
1. Client-side experimentation
If client-side experimentation is possible, prefer this approach. Serve a generic page with full page caching, then use the Contenzi Javascript SDK to vary the page.
2. Edge-Side Includes (ESI)
Use Edge Side Includes (ESI) to isolate the part of the page that requires variations, while caching the rest of the page. Include a snippet with variation using <esi:include />, generate the snippet using the standard PHP method described above.
3. Disabling caching for a specific page
If client-side and ESI are not suitable for the page, add a cache-control header to disable caching of this specific page. Ensure the performance of the non-cached page is adequate for the expected traffic levels.