qafoolabs/no-framework-bundle
A Symfony bundle for using Symfony components—dependency injection, routing, HTTP kernel, and more—without adopting the full framework, making it easier to add structure and modern features to legacy or lightweight PHP applications.
This package is archived and has been superseded by GyroProject MVC-Bundle; treat it as a legacy dependency, not a new adoption. If you are evaluating it for an existing project, confirm the Symfony version constraints in composer.json first — the bundle was built around Symfony 2/3-era component APIs and will not install cleanly against modern Symfony without conflict resolution.
Minimal steps to get a first response out of it:
composer require qafoolabs/no-framework-bundle in a project you control (expect abandoned-package warnings).QafooLabs\Bundle\NoFrameworkBundle\QafooLabsNoFrameworkBundle in your kernel/bundle list.services.yml with an explicit ID — there is no autowiring or autoconfiguration here.service_id:method).HttpKernel::handle(Request) and emits the Response.Where to look first in the repo:
README.md — the only place the service-controller convention is documented.DependencyInjection/ and Resources/config/ — what services are registered and what you can override.Tests/ — the fastest way to see a working route → service → Response cycle.Best first use case: a single JSON or HTML endpoint whose controller is a plain service with constructor-injected dependencies, returning a Response. That proves the whole value proposition — controllers without FrameworkBundle — before you migrate anything larger.
Service controllers as the primary unit. The package's reason to exist is treating controllers as ordinary services. Define them explicitly, inject collaborators through the constructor, and let the bundle's resolver turn a route's _controller value into a service call. Keep controllers thin — they are the seam between routing and your domain, and they should not depend on AbstractController helpers that don't exist here.
Route files, not attributes. Configure routes in YAML/XML/PHP and reference services by ID. Avoid relying on annotation/attribute route loading; the loader support is tied to the archived Symfony generation and is the first thing to break on upgrade.
Event listeners for cross-cutting concerns. Because you own the kernel wiring, use HttpKernel event subscribers for auth, CORS, request logging, and response post-processing. This replaces the bundles you'd normally get from FrameworkBundle and keeps concerns out of controllers.
Explicit kernel bootstrapping. Build your own Kernel/front controller: Request::createFromGlobals() → handle() → send() → terminate(). In tests, call the same handle() with a fabricated Request and assert on the Response — this is the cleanest way to get functional coverage without a full framework test client.
Gradual strangler usage. If you're extracting endpoints from a legacy app, mount this kernel behind a separate front controller (e.g. /api) and let the old app keep everything else. Do not try to mix this bundle and FrameworkBundle in the same kernel; the duplicate HttpKernel/routing services will fight.
Container as the composition root. Since there is no autowiring, invest in a tidy, explicit service file. That file becomes your architecture documentation, and it is the main thing you'll need to port to GyroProject MVC-Bundle or plain Symfony components later.
GyroProject MVC-Bundle, and the concepts (service controllers, explicit routes, own kernel) transfer almost 1:1.symfony/http-kernel, symfony/routing, and symfony/dependency-injection constraints before assuming it will install.AbstractController conveniences. render(), json(), redirectToRoute(), createForm(), and param converters are absent. Return Response/JsonResponse directly and resolve route parameters from Request.service:method shape exactly. A typo yields a "controller not callable" error deep in the resolver; log the resolved controller in dev to shorten that loop.FrameworkBundle's exception listener, uncaught exceptions bubble out of handle(). Register your own kernel.exception listener or wrap the front controller, and make sure kernel.debug toggles verbose output.kernel.request and kernel.response events, and keep a tiny script that boots the kernel and dumps the container. Because there's no profiler, event-level logging is your only visibility.How can I help you explore Laravel packages today?