Laravel Pennant manages feature flags using a database-backed system designed for simplicity and flexibility. Here's a detailed explanation of how it works:
**Database Storage and Setup
Pennant persists feature flags in a database table named `features`, which is created by running migrations provided by the package. This table stores the state of each feature flag, enabling persistent and environment-specific control over feature availability[2][4]. To get started, you install Pennant via Composer, publish its configuration and migration files, and run migrations to create the necessary database schema[2].
**Configuration
The package includes a configuration file (`config/pennant.php`) where you can specify the default storage driver. Pennant supports an in-memory `array` driver for temporary storage, but by default, it uses the `database` driver to persist feature flag states across requests and users[2].
**Defining Feature Flags
Feature flags are defined in your Laravel application using the `Feature` facade. You can define a simple flag by name, which is disabled by default:
php
Feature::define('new-feature');
Or define flags with conditional logic that determines when they are active, often based on the authenticated user or other criteria:
php
Feature::define('new-feature', function ($user) {
return $user->role === 'admin';
});
This closure-based definition allows for complex logic, such as enabling a feature only for admins, beta testers, or randomly selected users[3][4].
**Checking Feature Flags
In your application code, you check if a feature is active using:
php
if (Feature::active('new-feature')) {
// Feature-specific logic here
}
Pennant also provides methods to check if any or all features in a set are active, facilitating conditional logic based on multiple flags[3].
**Activating and Deactivating Flags
You can toggle feature flags dynamically. For example, to activate a feature for the current user:
php
Feature::activate('new-feature');
Or deactivate it:
php
Feature::deactivate('new-feature');
Pennant scopes feature flags to the authenticated user by default, but you can specify a different user or scope using `Feature::for($user)`. This allows enabling or disabling features for specific users programmatically, such as through an admin panel:
php
Feature::for($anotherUser)->activate('new-feature');
You can also activate or deactivate features globally for everyone:
php
Feature::activateForEveryone('new-feature');
Feature::deactivateForEveryone('new-feature');
This makes it easy to roll out features incrementally or quickly disable them if issues arise[3][4].
**Usage in Application
Feature flags can be used throughout your Laravel app-in controllers, middleware, views, or service classes-to conditionally enable or disable functionality without scattering conditional logic everywhere. This abstraction centralizes feature flag logic, improving maintainability and flexibility[3][7].
**Additional Features
Laravel Pennant supports class-based feature flags, scopes, eager loading, and custom drivers for storage. It integrates well with Laravel's authentication system, passing the current user to feature flag definitions automatically[2][7].
In summary, Laravel Pennant manages feature flags by storing their states in a dedicated database table, defining flags with flexible logic via closures, and providing a simple API to activate, deactivate, and check features scoped to users or globally. This approach offers a clean, maintainable, and scalable way to handle feature toggling in Laravel applications[2][3][4].
Citations:
[1] https://laravel-news.com/feature-flags-with-laravel-pennant
[2] https://laravel.com/docs/12.x/pennant
[3] https://www.honeybadger.io/blog/a-guide-to-feature-flags-in-laravel/
[4] https://dev.to/saurabh-dhariwal/how-to-manage-feature-flags-with-laravel-pennant-in-2024-1phb
[5] https://github.com/stephenjude/filament-feature-flags
[6] https://laravel.com/docs/11.x/pennant
[7] https://www.linkedin.com/pulse/why-laravel-pennant-help-you-roll-out-features-ease-mabugay-trxtc
[8] https://www.youtube.com/watch?v=EjLAaeHSPWY