Controllers
Plain PHP classes whose methods return a Response. Should stay thin — orchestrate, do not implement business logic.
- Extend `AbstractController` for handy shortcuts: `render()`, `redirectToRoute()`, `getUser()`, `addFlash()`, `denyAccessUnless...()`.
- You do not have to extend it — invokable controllers (`__invoke`) work as plain services.
- Inject services via constructor or method arguments — Symfony autowires both.
- Return a `Response`. Use `JsonResponse` for APIs, `RedirectResponse` for redirects, `BinaryFileResponse` for file downloads.
- Heavy logic belongs in services, not controllers. Controllers translate HTTP ↔ domain.
class UserController extends AbstractController
{
public function __construct(private UserService $users) {}
#[Route('/me', name: 'app_me')]
public function me(): Response
{
return $this->render('user/me.html.twig', [
'profile' => $this->users->getProfile($this->getUser()),
]);
}
}
Common gotchas
- Avoid `\$this->container->get()` in controllers — it is allowed for back-compat but hides dependencies.
- If a controller method returns void or null, Symfony will throw a confusing error. Always return a Response.