Skip to content
  • There are no suggestions because the search field is empty.

PHP Quickstart

Get Running with the Convert PHP SDK in 5 Minutes

THIS ARTICLE WILL HELP YOU:

Overview

The Convert PHP SDK lets you run Convert Full Stack experiments and feature flags from your PHP backend. This is useful when you want to decide what a visitor should see before the page is rendered, such as changing server-rendered HTML, pricing logic, checkout flows, API behavior, or backend-controlled feature access.

The PHP SDK is synchronous. Unlike browser-based or JavaScript SDK implementations, there is no onReady() promise. The SDK is ready immediately after ConvertSDK::create() returns, but you should still verify readiness with $sdk->isReady() before creating visitor contexts.

Convert Full Stack testing allows experiments to be handled across both frontend and backend layers, which can help optimize the full user experience, not only DOM-level changes.

1. Install the PHP SDK

Install the SDK with Composer:

composer require convertcom/php-sdk

The install includes Guzzle as the default PSR-18 HTTP client, so no extra HTTP client installation is needed for the standard setup.

If you want to use a different PSR-18 compatible client, see the SDK installation documentation for swapping the PSR-18 client.

2. Full Working Example

Use the following copy-paste-ready example to initialize the SDK, create a visitor context, run an experience, evaluate a feature flag, and track a purchase conversion with revenue.

<?php

declare(strict_types=1);

use ConvertSdk\ConvertSDK;
use ConvertSdk\DTO\BucketedVariation;
use ConvertSdk\DTO\BucketedFeature;
use ConvertSdk\DTO\ConversionAttributes;
use ConvertSdk\DTO\GoalData;
use ConvertSdk\Enums\FeatureStatus;
use ConvertSdk\Enums\GoalDataKey;

// 1. Initialize the SDK
$sdk = ConvertSDK::create([
    'sdkKey' => 'your-sdk-key',
]);

// 2. Verify the SDK is ready
if (!$sdk->isReady()) {
    die('SDK failed to initialize');
}

// 3. Create a visitor context
$context = $sdk->createContext('visitor-123', [
    'country' => 'US',
    'plan'    => 'premium',
]);

// 4. Run an experience
/** @var BucketedVariation|null $variation */
$variation = $context->runExperience('homepage-redesign');

if ($variation !== null) {
    echo "Experience: {$variation->experienceKey}\n";
    echo "Variation:  {$variation->variationKey}\n";
}

// 5. Resolve a feature flag
/** @var BucketedFeature|null $feature */
$feature = $context->runFeature('dark-mode');

if ($feature !== null && $feature->status === FeatureStatus::Enabled) {
    $theme = $feature->variables['theme'] ?? 'dark';
    echo "Dark mode theme: {$theme}\n";
}

// 6. Track a conversion with revenue
$context->trackConversion('purchase-completed', new ConversionAttributes(
    conversionData: [
        new GoalData(GoalDataKey::Amount, 49.99),
        new GoalData(GoalDataKey::TransactionId, 'txn-abc-123'),
    ],
));

// Events auto-flush on shutdown in PHP-FPM, or flush manually:
$sdk->flush();

3. Key Points

PHP SDK readiness

The PHP SDK is fully synchronous. There is no onReady() promise. The SDK is ready immediately after ConvertSDK::create() returns.

You should still check:

if (!$sdk->isReady()) {
    die('SDK failed to initialize');
}

before creating contexts or running experiences.

Use the static factory

ConvertSDK uses a static factory method. Initialize it with:

$sdk = ConvertSDK::create([
    'sdkKey' => 'your-sdk-key',
]);

Do not instantiate it directly with new ConvertSDK(), because the constructor is private.

Use a stable visitor ID

Use a stable visitor identifier when creating a context:

$context = $sdk->createContext('visitor-123');

For logged-in users, use a stable internal user ID. For anonymous visitors, use a persistent first-party cookie or another stable anonymous identifier. A stable visitor ID helps keep assignment consistent across requests and sessions while the experience configuration remains unchanged. If the experience configuration changes, the visitor may be re-bucketed; to preserve assignment stability across sessions and configuration changes, configure a persistent DataStore such as RedisStore.

Auto-flush and manual flush

In PHP-FPM environments, queued tracking events flush automatically on shutdown.

For CLI scripts, workers, cron jobs, or long-running processes, call:

$sdk->flush();

explicitly after tracking events.

4. Running an Experience

Use runExperience() with the experience key configured in Convert:

$variation = $context->runExperience('homepage-redesign');

If the visitor qualifies for the experience, the SDK returns a bucketed variation. You can then use that decision to render different server-side content.

Example:

$variation = $context->runExperience('homepage-redesign');

if ($variation !== null && $variation->variationKey === 'variation-a') {
    include 'templates/homepage-variation-a.php';
} else {
    include 'templates/homepage-original.php';
}

This approach is useful when the variation should be decided before the HTML is sent to the browser.

5. Resolving a Feature Flag

Use runFeature() with the feature key configured in Convert:

$feature = $context->runFeature('dark-mode');

You can then check the feature status and read feature variables:

if ($feature !== null && $feature->status === FeatureStatus::Enabled) {
    $theme = $feature->variables['theme'] ?? 'dark';
}

Feature flags are useful for gradually rolling out backend-controlled features, enabling functionality for selected audiences, or testing different feature configurations.

6. Tracking Conversions and Revenue

Use trackConversion() to send goal completions to Convert.

Example purchase conversion:

$context->trackConversion('purchase-completed', new ConversionAttributes(
    conversionData: [
        new GoalData(GoalDataKey::Amount, 49.99),
        new GoalData(GoalDataKey::TransactionId, 'txn-abc-123'),
    ],
));

Use this when a visitor completes a meaningful action such as:

  • completing a purchase
  • submitting a form
  • starting a subscription
  • completing onboarding
  • activating a feature
  • reaching a backend-defined milestone

7. Front-End Considerations

The PHP SDK decides the visitor’s experience or feature variation on the backend. However, many implementations still need a front-end plan for rendering, tracking, analytics integrations, or client-side behavior.

There are two common implementation patterns.

Pattern A: Server-Side Rendering Only

Use this approach when PHP controls the full page output.

Example:

$variation = $context->runExperience('homepage-redesign');

if ($variation !== null && $variation->variationKey === 'new-hero') {
    echo '<h1>Try our new checkout experience</h1>';
    echo '<a href="/checkout" class="button">Start checkout</a>';
} else {
    echo '<h1>Welcome to our store</h1>';
    echo '<a href="/products" class="button">Shop now</a>';
}

In this setup:

  • the backend decides the variation
  • the visitor receives the correct HTML immediately
  • flicker is reduced because the browser does not need to wait for DOM changes
  • backend logic and frontend output stay aligned

Server-side testing is commonly used to minimize content flash, support server-rendered pages, control backend-side variation logic, and preserve experiment tracking integrity.

Pattern B: Backend Decision + Front-End Behavior

Use this approach when PHP decides the variation, but JavaScript still needs to react to that decision.

For example, PHP can expose the assigned variation to the front end:

$variation = $context->runExperience('homepage-redesign');

$variationKey = $variation !== null ? $variation->variationKey : 'original';
?>

<script>
window.convertAssignedVariation = <?php echo json_encode($variationKey); ?>;
</script>

Then your front-end code can read it:

<script>
if (window.convertAssignedVariation === 'new-hero') {
    document.documentElement.classList.add('convert-new-hero');
}
</script>

This is useful when:

  • PHP renders the initial HTML
  • JavaScript controls interactive components
  • analytics tools need front-end metadata
  • a SPA or hydrated frontend needs to know which variation was assigned

For full-stack experimentation, Convert recommends keeping frontend and backend logic consistent so the visitor receives a coherent experience across the full application.

Avoid Duplicate Bucketing

Do not run the same experiment independently in both PHP and browser JavaScript unless your implementation is intentionally designed for that.

If the PHP SDK decides the variation server-side, avoid also letting the front-end tracking script or another SDK re-decide the same visitor into a different variation.

To avoid inconsistent results:

  • use the same stable visitor ID
  • keep one source of truth for variation assignment
  • pass the backend decision to the frontend when needed
  • QA the assigned variation in both server-rendered output and browser behavior

Convert’s full-stack and web testing guidance emphasizes maintaining consistency between server-side assignment and client-side tracking when both are used together.

8. QA Checklist

Before launching your PHP SDK implementation, verify the following:

  • The SDK is installed with Composer.
  • ConvertSDK::create() is used instead of calling the constructor directly.
  • $sdk->isReady() is checked before creating contexts.
  • The visitor ID is stable across requests.
  • The correct experience key is used in runExperience().
  • The correct feature key is used in runFeature().
  • Conversion goal keys match the goals configured in Convert.
  • Revenue values and transaction IDs are passed correctly.
  • $sdk->flush() is called manually in CLI or long-running scripts.
  • Front-end code does not re-bucket visitors into conflicting variations.
  • The rendered HTML matches the assigned variation.
  • Analytics and downstream tools receive the intended experiment or variation metadata, if applicable.

9. Troubleshooting

SDK failed to initialize

Check that the SDK key is valid and that the SDK is initialized with:

$sdk = ConvertSDK::create([
    'sdkKey' => 'your-sdk-key',
]);

Then verify:

$sdk->isReady();

Visitor sees different variations

This usually means the visitor ID is changing between requests or the same experiment is being evaluated separately in more than one place.

Use a stable visitor ID, such as a logged-in user ID or persistent anonymous cookie.

Conversions do not appear in reports

Check that:

  • the goal key is correct
  • the visitor context is created successfully
  • the conversion is tracked after the relevant action
  • $sdk->flush() is called in CLI or long-running processes
  • the visitor was eligible for the relevant experience

Front-end does not match backend variation

Make sure the PHP-assigned variation is passed to the browser if front-end JavaScript needs to know the assigned variation.

Example:

<script>
window.convertAssignedVariation = <?php echo json_encode($variationKey); ?>;
</script>

Then confirm that your JavaScript reads this value instead of making a separate variation decision.

Conclusion

The Convert PHP SDK provides a fast way to run server-side experiments and feature flags in PHP applications. Install it with Composer, initialize it with your SDK key, create a stable visitor context, and use runExperience(), runFeature(), and trackConversion() to control experiences and measure results.

For frontend-facing implementations, decide whether PHP will fully render the variation or whether the backend decision also needs to be passed into JavaScript. Keeping the backend and frontend aligned is essential for consistent visitor experiences and accurate experiment reporting.