Security, Events & Async Messaging
Security & Voters
# config/packages/security.yaml
security:
firewalls:
main:
lazy: true
provider: app_user_provider
form_login:
login_path: app_login
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/account, roles: ROLE_USER }<?php
// Fine-grained authorization beyond role checks
class PostVoter extends Voter
{
protected function supports(string $attribute, mixed $subject): bool
{
return $attribute === 'EDIT' && $subject instanceof Post;
}
protected function voteOnAttribute(string $attribute, mixed $post, TokenInterface $token): bool
{
$user = $token->getUser();
return $user instanceof User && $post->getAuthor() === $user;
}
}
// In a controller:
$this->denyAccessUnlessGranted('EDIT', $post);Events & Subscribers
<?php
// Subscriber — declares its own subscribed events, discovered via autoconfiguration
class MaintenanceModeSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [KernelEvents::REQUEST => 'onKernelRequest'];
}
public function onKernelRequest(RequestEvent $event): void
{
if (MaintenanceMode::isEnabled()) {
$event->setResponse(new Response('Down for maintenance', 503));
}
}
}
// Implementing EventSubscriberInterface is enough — no services.yaml tagging needed.Messenger (Async Jobs)
<?php
final class SendWelcomeEmail
{
public function __construct(public readonly string $userId) {}
}
#[AsMessageHandler]
class SendWelcomeEmailHandler
{
public function __invoke(SendWelcomeEmail $message): void
{
// runs on a worker, off the request cycle
$this->mailer->send(...);
}
}
// Dispatch from a controller — returns immediately, worker processes it later
$this->messageBus->dispatch(new SendWelcomeEmail($user->getId()));
// Run the worker:
// php bin/console messenger:consume asyncTesting
<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ArticleControllerTest extends WebTestCase
{
public function testShowArticle(): void
{
$client = static::createClient();
$client->request('GET', '/articles/1');
$this->assertResponseIsSuccessful();
$this->assertSelectorTextContains('h1', 'My Article');
}
}Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free