Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Feature Checker Bundle Laravel Package

lwiesel/feature-checker-bundle

A Symfony bundle for feature checking and toggles. Define features, evaluate them in services, controllers, and Twig templates, and enable or disable functionality per environment, user, or rollout without redeploying code. Supports configurable checks and gradual releases.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a thin, config-driven feature flag layer for Symfony2. There is no database, no admin UI, and no per-user targeting — flags are declared in YAML and evaluated at runtime. That makes it a good fit for simple "ship dark code" toggles, not for experimentation platforms.

1. Install (verify constraints first — this is a 2015 package):

composer require lwiesel/feature-checker-bundle

Before committing, check composer.json in the repo. It targets Symfony ~2.3-era APIs and PHP 5.x. If you are on Symfony 3.4+ you will likely need to fork it and relax the constraints, or wrap the concept in your own tiny service instead.

2. Register the bundle in app/AppKernel.php:

public function registerBundles()
{
    $bundles = array(
        // ...
        new Lwiesel\FeatureCheckerBundle\LwieselFeatureCheckerBundle(),
    );
}

3. Look here first: open Resources/config/services.xml (or .yml) in the bundle. That file tells you the exact service id and class name for the checker and the Twig extension. The README is minimal; the DI config is the source of truth for how you wire it into your app. Confirm whether the public service id is lwiesel_feature_checker.checker, lwiesel_feature_checker, or similar, and use debug:container to list it:

php app/console debug:container | grep -i feature

4. Declare your flags under the bundle's config key (typically lwiesel_feature_checker):

# app/config/config.yml
lwiesel_feature_checker:
    features:
        new_checkout: false
        beta_reports: true
        legacy_import: true

5. First use case — guard a new controller action:

public function checkoutAction()
{
    $checker = $this->get('lwiesel_feature_checker.checker');

    if ($checker->isEnabled('new_checkout')) {
        return $this->render('AcmeShopBundle:Checkout:new.html.twig');
    }

    return $this->render('AcmeShopBundle:Checkout:legacy.html.twig');
}

That is the whole value proposition: one line of config flips a branch of your code, per environment, without a deploy of new logic.

Implementation Patterns

Environment-scoped flags. The highest-leverage pattern is overriding the flag set per environment. Declare everything in config.yml, then turn things on in config_dev.yml so developers always exercise the new path, while production stays dark until you are ready:

# app/config/config_dev.yml
lwiesel_feature_checker:
    features:
        new_checkout: true

Twig usage. If the bundle registers its Twig extension (check services.xml for a TwigExtension class), you get a template-level check. Typical shape:

{% if feature_is_enabled('beta_reports') %}
    {% include 'AcmeReportBundle:Report:beta.html.twig' %}
{% endif %}

If the extension is not registered automatically, add it to config.yml under twig.globals or register the service tag twig.extension manually.

Wrap the checker in your own service. Do not scatter $this->get('lwiesel_feature_checker.checker') across controllers. Inject it once into an application service and expose meaningful names:

class CheckoutFeatures
{
    private $checker;

    public function __construct($checker)
    {
        $this->checker = $checker;
    }

    public function isNewCheckoutEnabled()
    {
        return $this->checker->isEnabled('new_checkout');
    }
}

This gives you one place to change when you eventually replace the abandoned bundle with a maintained flag library — your controllers and templates keep calling isNewCheckoutEnabled().

Keep flags out of domain logic. Feature checks belong at the edges (controllers, listeners, Twig), not inside entities or repositories. A repository that reads a flag becomes untestable and couples your data layer to deployment configuration.

Flag lifecycle discipline. Adopt a convention for naming and retirement:

  • Name flags after the capability, not the team or ticket: new_checkout, not acme_1234.
  • Every flag gets an owner and a removal date in a comment.
  • Delete the flag and the dead branch in the same PR that makes it permanent. With config-only flags there is nothing to clean up on the infrastructure side, which makes this easier than with a DB-backed tool.

Canary via config, not code. Because flags are static per environment, a practical rollout is: flip the flag to true in a staging config, run smoke tests, then flip it in production config and deploy. The deploy itself becomes a no-op logic change; the flag flip is the actual switch.

Pair with Symfony's own tools. For anything requiring per-user or percentage rollout, this bundle will not help. Use it alongside a voter or a request listener that combines the static flag with user attributes:

if ($this->get('lwiesel_feature_checker.checker')->isEnabled('beta_reports')
    && $this->get('security.authorization_checker')->isGranted('ROLE_BETA')) {
    // ...
}

Gotchas and Tips

It is effectively unmaintained. Last release March 2015, 13 stars, zero dependents. Treat it as a small, vendored utility. If you need long-term support, either fork it into your own AcmeFeatureBundle (the logic is small enough to reimplement in an afternoon) or use a maintained alternative. Do not build a critical rollout process on top of it without a fork.

Symfony version compatibility is the first blocker. The bundle predates Symfony 3's service changes and Symfony 4's bundle-less structure. On modern Symfony you will hit AppKernel, services.xml tag, and Twig API deprecations. Budget time for a fork rather than expecting composer require to just work.

Config caching will bite you in prod. Symfony caches the compiled container. After editing flag YAML, you must clear the cache (php app/console cache:clear --env=prod) or the old flags remain active. In dev this is automatic; in prod it is a deploy step. Document it.

YAML boolean parsing. true/false are parsed as booleans, but yes/no/on/off and quoted "false" behave differently depending on the Symfony YAML version. Always use unquoted true/false and verify with a quick var_dump of the resolved config. A flag set to the string "false" is truthy in PHP — a classic silent bug.

Service id guessing wastes time. The README may not state the exact service id. Run debug:container (or container:debug on older Symfony) and grep for feature. Also check whether the service is public; in newer Symfony versions private services cannot be fetched via $this->get() from a controller.

No runtime mutation. You cannot toggle a flag from an admin panel or a database row. If a product manager asks "can we turn this on for one customer without a deploy?", the answer with this bundle is no. Set expectations early or add a thin layer that reads overrides from a settings table and falls back to the bundle's config.

Testing flags. Because the checker reads from config, functional tests can override the container parameter or redefine the checker service in a test-specific config file. Do not test both branches in the same test class without resetting the container — the compiled config is shared.

Watch for flag sprawl. The low friction of adding a YAML key encourages accumulation. Without a removal process you will end up with dozens of flags where nobody knows which are safe to delete. Keep a FEATURES.md or a comment block listing owner and expiry for each flag.

Do not leak flag names to clients. If you expose feature_is_enabled results in JSON APIs, you reveal unreleased roadmap items. Keep flags server-side unless the exposure is deliberate.

Extension point is the config tree. The Configuration class defines the shape of the config tree. If you need richer flag semantics (e.g., per-flag metadata like owner or expiry), that is where you would extend — but at that point you are better off writing your own bundle with a clean config tree and explicit service definitions.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style