francisbesset/sfcontextbundle
Symfony bundle providing a centralized context service inspired by Symfony 1's sfContext, offering convenient access to the current request, response, user, and other shared application services. It simplifies managing context dependencies with straightforward configuration.
francisbesset/sfContextBundle reintroduces Symfony 1.x's sfContext singleton into Symfony 2. It exists for one reason: to let code written against sfContext::getInstance()->… keep running after a Symfony 1 → Symfony 2 migration, without rewriting every call site on day one.
Before you install anything, confirm you actually qualify:
AppKernel/XML-service-definition style, and will not install against Symfony 4/5/6/7 (composer require will fail on version constraints, and the code relies on APIs removed long ago).sfContext call sites to port — helpers, legacy bundles, third-party SF1 code. If you don't, this bundle adds nothing.composer.json / Packagist entry before installing; the repository directory is sfContextBundle but the published package name may be hyphenated.Minimal wiring:
// app/AppKernel.php
public function registerBundles()
{
$bundles = [
// ...
new FrancisBesset\Bundle\sfContextBundle\sfContextBundle(),
];
return $bundles;
}
First use case — the one this bundle is built for:
// A legacy SF1 helper you have not ported yet
$request = sfContext::getInstance()->getRequest();
$user = sfContext::getInstance()->getUser();
$response = sfContext::getInstance()->getResponse();
Look first at the bundle's service definition (usually Resources/config/services.xml) to see which container services are exposed through the context and under which method names. That mapping is the contract you'll be porting against.
1. Thin adapter around the singleton. Don't sprinkle sfContext::getInstance() through new code. Introduce one class that wraps it, then inject that class. When you're ready to drop the bundle, you change one file:
final class LegacyContext
{
public function request(): Request
{
return sfContext::getInstance()->getRequest();
}
// ...
}
2. Bridge legacy libraries. If you're pulling in SF1-era code (a mailer helper, an ACL check), wrap the entry point in a Symfony 2 service that constructs the sfContext state once from the request stack, calls the legacy code, and returns a value. Keep the singleton at the boundary, never in the core.
3. Templates. Expose a small Twig global/extension delegating to your adapter rather than calling sfContext directly from templates — templates are exactly where untestable global state rots fastest.
4. Incremental porting order. Port in this sequence: request/response access → user/session → routing → logging/i18n. The first two are trivially replaceable by RequestStack and TokenStorage; routing and i18n are where the bundle buys you the most breathing room.
5. Feature-flag the shim. Put legacy call sites behind a config flag so you can run the app both with and without the bundle and measure how much is left to port.
sfContext had in SF1 comes along: hidden dependencies, untestable units, and initialization-order bugs. Treat it as scaffolding with a demolition date, not architecture.getRequest() call in those contexts returns null or throws depending on how the bundle was initialized — guard every non-web entry point.RequestStack. Under ESI/fragment rendering or forwarded sub-requests, the "current" request the context reports may not be the one you think. Don't trust it inside fragment controllers.sfContext service must be explicitly public: true to be retrievable from $container->get(). Older definitions assume the default was public.composer.json, vendor the bundle into your repo if you need to patch it, and expect no upstream fixes.sfContext::getInstance() occurrences (a grep in CI is enough) as a burn-down metric, and delete the bundle when the count hits zero.How can I help you explore Laravel packages today?