Search by

mocodo / flipt-sdk

mocodo

PHP SDK for Flipt feature flag evaluation, built on PSR-18/PSR-17.

v1.0.0 2026-08-21 19:42 UTC

README

PHP SDK for Flipt feature flag evaluation, built on PSR-18/PSR-17.

It wraps Flipt's evaluation API (/evaluate/v1/boolean, /evaluate/v1/variant, /evaluate/v1/batch) behind a small, typed client. It talks to any PSR-18 HTTP client and PSR-17 factories, so it works with whichever HTTP stack your project already uses (Guzzle, Symfony HTTP client, ...).

Requirements

  • PHP ^8.2
  • A PSR-18 HTTP client implementation
  • PSR-17 HTTP factories (request + stream)

This package depends on php-http/discovery to auto-detect an installed PSR-18 client and PSR-17 factories when you don't pass them explicitly. Discovery's Composer plugin is disabled by default in this package's own composer.json (allow-plugins.php-http/discovery: false), so make sure your project requires a concrete implementation, for example:

composer require symfony/http-client nyholm/psr7
# or
composer require guzzlehttp/guzzle http-interop/http-factory-guzzle

Installation

composer require mocodo/flipt-sdk

Quickstart

use Mocodo\FliptSdk\FliptClient;
use Mocodo\FliptSdk\Model\EvaluationRequest;

$client = new FliptClient(
    baseUrl: 'https://flipt.example.com',
    clientToken: 'my-flipt-api-token', // optional
);

If you omit the HTTP client/factories, they're auto-discovered via php-http/discovery. You can also pass them explicitly as the 2nd–4th constructor arguments if you want full control (e.g. a pre-configured Guzzle client).

Boolean evaluation

$request = new EvaluationRequest(
    flagKey: 'new-checkout-flow',
    entityId: 'user-123',
    context: ['plan' => 'enterprise'],
);

$response = $client->evaluateBoolean($request);

if ($response->isEnabled()) {
    // ...
}

Variant evaluation

$request = new EvaluationRequest(
    flagKey: 'pricing-experiment',
    entityId: 'user-123',
);

$response = $client->evaluateVariant($request);

if ($response->isMatch()) {
    echo $response->getVariantKey();
}

Batch evaluation

Evaluate several flags at once for the same entity/context:

$results = $client->evaluateBatch(
    entityId: 'user-123',
    flagKeys: ['new-checkout-flow', 'pricing-experiment'],
    context: ['plan' => 'enterprise'],
);

foreach ($results as $flagKey => $result) {
    // $result is a BooleanEvaluationResponse, VariantEvaluationResponse,
    // or ErrorEvaluationResponse, depending on the flag's evaluation type
}

Error handling

Every exception this SDK throws implements Mocodo\FliptSdk\Exception\FliptExceptionInterface:

  • FliptApiException β€” the Flipt API returned a non-2xx response, or a response that couldn't be parsed as JSON. Carries getStatusCode() and getResponseBody().
  • FliptTransportException β€” the underlying PSR-18 client failed to send the request (network error, etc.). Carries the original ClientExceptionInterface as getPrevious().
use Mocodo\FliptSdk\Exception\FliptApiException;
use Mocodo\FliptSdk\Exception\FliptTransportException;

try {
    $response = $client->evaluateBoolean($request);
} catch (FliptApiException $exception) {
    // Flipt responded, but with an error or an unexpected payload
} catch (FliptTransportException $exception) {
    // Couldn't reach Flipt at all
}

Testing

composer test      # phpunit
composer phpstan    # static analysis

Releasing

Releases are fully automated by semantic-release from Conventional Commits (feat:, fix:, BREAKING CHANGE:, ...) landing on main.

  1. Merge Conventional Commit-formatted commits into main as usual.
  2. The semantic-release CI job (stage release, defined in .gitlab-ci/release.yml) inspects the commits since the last release, computes the next semver version, updates CHANGELOG.md, commits it (chore(release): X.Y.Z [skip ci]), tags it X.Y.Z, and publishes a GitLab Release.
  3. The resulting tag pipeline re-runs the full test/static/security suite as a post-release check.
  4. Packagist is pointed at this repository (via a webhook); it syncs automatically from new tags.

This requires a project access token (write_repository + api scope, Maintainer role) stored as the masked/protected GITLAB_TOKEN CI/CD variable, and main's protected-branch settings must allow that token's bot user to push directly.

License

MIT