Using feature flags in Laravel (supashiphq/php-sdk)
Use Supaship\SupaClient as a Laravel service container singleton and refresh evaluation context after the authenticated user is known (middleware or afterResolving). The Packagist package supashiphq/php-sdk runs on PHP 7.4+; the snippets below use PHP 8.1+ syntax (e.g. readonly constructor promotion).
Prerequisites: PHP SDK overview — install via Composer, obtain a Server SDK key, define fallback flags in config.
1. Environment variables
In .env:
SUPASHIP_SDK_KEY=your-sdk-key
SUPASHIP_ENVIRONMENT=production2. Laravel config file
Create config/supaship.php:
<?php
return [
'sdk_key' => env('SUPASHIP_SDK_KEY'),
'environment' => env('SUPASHIP_ENVIRONMENT', 'production'),
/**
* Central list of flags and fallbacks — keep in sync with what you use in Supaship.
*/
'features' => [
'new-ui' => false,
'theme-config' => [
'primaryColor' => '#007bff',
'darkMode' => false,
],
],
];3. Register SupaClient as a singleton
In app/Providers/AppServiceProvider.php (register()):
use Illuminate\Support\ServiceProvider;
use Supaship\SupaClient;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(SupaClient::class, function ($app) {
$config = $app['config']->get('supaship');
return new SupaClient([
'sdkKey' => $config['sdk_key'],
'environment' => $config['environment'],
'features' => $config['features'],
'context' => [
// Filled at boot or request time — see below
'appEnv' => config('app.env'),
],
]);
});
}
}4. Per-request user context (targeting)
After Auth resolves (e.g. in AppServiceProvider::boot() or route middleware), call updateContext so user targeting and percentage rollouts use the correct user id and attributes:
use Illuminate\Support\Facades\Auth;
use Supaship\SupaClient;
public function boot(): void
{
$this->app->afterResolving(SupaClient::class, function (SupaClient $client) {
$user = Auth::user();
if ($user) {
$client->updateContext([
'userId' => (string) $user->id,
'email' => $user->email ?? '',
]);
}
});
}Dedicated middleware that only calls updateContext is often clearer when you need Auth::user() on every HTTP request.
5. Controller injection
use Supaship\SupaClient;
class DashboardController extends Controller
{
public function __construct(private readonly SupaClient $features) {}
public function index()
{
$showNewUi = $this->features->getFeature('new-ui');
$theme = $this->features->getFeature('theme-config');
return view('dashboard', compact('showNewUi', 'theme'));
}
}PHPUnit and HttpStub
Register a SupaClient wired with Supaship\Testing\HttpStub and swap the container binding before exercising the route — see the PHP overview — testing and PHP SDK — Laravel route tests .