Symfony Framework
What is Symfony?
Symfony is a mature, modular PHP framework used by enterprises and as the foundation for Laravel, Drupal, and API Platform. Its reusable components can be adopted independently.
Creating a Project
composer create-project symfony/skeleton myapp
cd myapp
composer require webapp
symfony server:start
Routing and Controllers
// src/Controller/HelloController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HelloController extends AbstractController
{
#[Route('/hello/{name}', name: 'app_hello')]
public function hello(string $name): Response
{
return $this->render('hello.html.twig', ['name' => $name]);
}
}
Twig Templates
{# templates/hello.html.twig #}
<h1>Hello, {{ name }}!</h1>
Doctrine ORM
composer require symfony/orm-pack
php bin/console make:entity Product
php bin/console make:migration
php bin/console doctrine:migrations:migrate
// src/Entity/Product.php
#[ORM\Entity]
class Product
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private string $name = '';
}
$product = new Product();
$product->setName('Widget');
$entityManager->persist($product);
$entityManager->flush();
Dependency Injection
Symfony’s service container wires dependencies automatically:
public function __construct(
private ProductRepository $productRepository
) {}
Configure services in config/services.yaml.
Console Commands
php bin/console make:command app:greet
php bin/console list
php bin/console cache:clear
Symfony vs Laravel
| Aspect | Symfony | Laravel |
|---|---|---|
| Philosophy | Components-first, explicit | Convention over configuration |
| Learning curve | Steeper | Gentler |
| Best for | Enterprise, long-term APIs | Rapid web apps, startups |
| ORM | Doctrine | Eloquent |
Both are excellent choices — Symfony excels when you need fine-grained control and reusable components.
Symfony Flex and Recipes
Modern Symfony projects use Flex to auto-configure bundles. When you run composer require symfony/mailer, Flex adds config files and env variables automatically.
Validation Component
use Symfony\Component\Validator\Validation;
$validator = Validation::createValidator();
$violations = $validator->validate($email, [new Email(), new NotBlank()]);
foreach ($violations as $violation) {
echo $violation->getMessage();
}
Event System
Symfony’s event dispatcher decouples components:
// src/EventSubscriber/OrderSubscriber.php
class OrderSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents(): array {
return [OrderPlacedEvent::class => 'onOrderPlaced'];
}
public function onOrderPlaced(OrderPlacedEvent $event): void {
// Send confirmation email
}
}
Environment Configuration
Symfony uses .env files with %env(VAR_NAME)% in YAML config:
# config/packages/doctrine.yaml
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
Run php bin/console debug:config doctrine to inspect resolved settings.
Testing with PHPUnit
composer require --dev symfony/test-pack
php bin/phpunit
Symfony provides WebTestCase for functional HTTP tests and KernelTestCase for service container tests.
Common Pitfalls
- Clearing cache after config changes:
php bin/console cache:clear. - Forgetting to warm cache in production after deploy.
- Mixing annotation and attribute routing during migration — pick one style per project.