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

Sfcontext Bundle Laravel Package

theofidry/sfcontext-bundle

A Symfony bundle that integrates SfContext, giving your application a simple way to define and access shared context from services, controllers, and templates. It keeps context handling centralized and consistent across your Symfony project.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're installing first. theofidry/sfcontext-bundle is a deliberately tiny bundle whose sole job is to hand you the Symfony container from a static call. It is archived (last release December 2019) and has effectively zero adoption, so treat it as a legacy-code bridge, not a foundation.

  1. Install it pinned to a compatible Symfony version. The bundle predates Symfony 5 and PHP 8. Before composer require theofidry/sfcontext-bundle, read its composer.json constraints — expect symfony/framework-bundle: ^3.4 || ^4.x and PHP 7.x. On a modern app the install will fail or pull ancient transitive deps; on a Symfony 4.4 LTS app it slots in cleanly.
  2. Register the bundle, either in config/bundles.php (SfContext\SfContextBundle::class => ['all' => true]) or AppKernel::registerBundles() for older skeletons.
  3. Read the source, not the docs. There is essentially one file that matters: the static holder class (the Context class in src/) plus the bundle class that populates it during kernel boot. That's the entire API surface — a getContainer()/get($id)-style accessor pair. Confirm the exact method names and namespace from the repo, because the README is minimal and the package is too small to have generated years of blog posts you can crib from.
  4. First use case: code that cannot take constructor injection. A Twig extension, a Doctrine fixture, a legacy include-style script, or a third-party library that calls back into a global. Write one smoke test that boots the kernel and asserts Context::get('some_service') returns the expected instance — that single test tells you whether the bundle's boot wiring is even working in your Symfony version.

If that smoke test is the only thing you need, seriously consider skipping the bundle and using KernelInterface/ContainerInterface passed explicitly, or ServiceSubscriberInterface. The bundle earns its place only when you have many call sites in code you don't control.

Implementation Patterns

Use it as a boundary adapter, not as a service locator sprinkled everywhere. The healthy pattern is: static call at the outer edge (legacy controller, CLI entry point, test bootstrap), then immediately hand the concrete service to plain classes via constructor injection. That keeps the static surface to a handful of files that you can grep and remove later.

// Legacy entry point only
$mailer = Context::get('app.mailer');
$notifier = new OrderNotifier($mailer);   // everything below is DI-clean

Wrap string IDs behind typed helpers. Don't scatter Context::get('app.foo') across the codebase — string IDs silently break on refactors and are invisible to debug:container. Put one small facade per domain in front of it:

final class Services
{
    public static function mailer(): MailerInterface
    {
        return Context::get(MailerInterface::class);
    }
}

Now a rename is one edit, and static analysis can at least see the return type.

Testing pattern — reset the holder explicitly. The container reference is process-global, so it survives tearDown() and leaks between tests. In your base TestCase:

protected function setUp(): void
{
    self::bootKernel();          // populates the static holder via kernel boot
}

protected function tearDown(): void
{
    Context::reset();            // or whatever the bundle exposes; otherwise null the reference manually
    parent::tearDown();
}

If the bundle has no reset method, keep your own Context::setContainer(null)-style helper in the test bootstrap rather than touching production code for test convenience.

Reuse WebTestCase. Inside functional tests, self::bootKernel() gives you a real container, so you can assert against services fetched statically without mocking. This is the fastest way to prove a migration path: write the assertion against Context::get(...) today, then swap to self::getContainer()->get(...) when you drop the bundle.

Migrating away (the actual long-term pattern). Because the bundle is archived, every adoption should come with an exit plan: replace static calls with constructor injection, one facade method at a time. Because you funnelled everything through Services::mailer()-style helpers, that's a mechanical change — make each helper resolve a service you inject at bootstrap instead of reading the container.

Gotchas and Tips

  • Abandoned is the headline. Archived since 2019, one release, four stars, zero dependents. No security fixes, no PHP 8 support guaranteed, and no Symfony 5/6 compatibility work. Pin it, and budget for removing it. If your app is on Symfony 5.3+, use #[Autowire], ServiceSubscriberInterface, or an explicit ContainerInterface parameter instead — all built in, all maintained.
  • Private services are not reachable. Symfony 4+ made services private by default and the compiler pass strips unreferenced ones. Context::get('app.foo') will throw or return null for anything not explicitly public: true or aliased. That's a real constraint: you'll be tempted to mark services public, which disables inlining and container optimizations and undoes the main perf benefit of the DIC.
  • Errors surface late, at the call site. Static resolution is lazy. A typo'd service ID, a missing alias, or a circular reference blows up at runtime in whatever request hits that line first — not at cache warmup. Add an integration test that exercises every static lookup if you adopt this widely.
  • Stale container in long-running workers. Under RoadRunner, Swoole, or Messenger workers, the static reference can outlive the container it points to after a kernel reboot or cache clear. Clear the reference at request/message boundaries, otherwise you'll get "service is not shared" style oddities and memory growth.
  • Cache clears in dev. The dev container is rebuilt on config changes; a holder populated in one boot can reference a container class that no longer exists on disk, producing confusing Class not found errors that a bin/console cache:clear fixes. If something works in prod but not dev, suspect the static holder before your config.
  • The container is not a service locator API contract. Anything you get this way will not appear in Symfony's debug tooling as a dependency — debug:container --deprecations, linting, and "unused service" reporting all miss it. Keep a grep list of static call sites in the README so the next developer can find them.
  • No meaningful extension points. It's a bundle class plus one static class; there's nothing to decorate or configure. If you need behaviour beyond what's there (per-request scoping, lazy proxies, contextual resolution), fork the single file into your own project rather than trying to extend it — that also removes the abandoned dependency.
  • Deprecation lineage. This is the same static-container pattern Symfony deprecated with ContainerAwareInterface/ContainerAwareTrait in 4.1 and removed in 6.0. Expect reviewers and static analysers to flag it; document why each call site exists (third-party callback, legacy script) so it doesn't look like an accident.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource