Symfony
The Symfony MVC Framework
For full documentation visit symfony.com.
Over 10 Years | Multiple Projects | Preferred
Symfony is a highly professional, open-source PHP framework designed to build scalable, high-performance web applications and APIs. It functions both as a full-stack framework and a set of independent, reusable PHP packages called components. These components are so robust that they power many other major web applications, including Laravel, Drupal, and Magento.
Key Features of Symfony
-
Model-View-Controller (MVC): Separates business logic, server actions, and layout.
-
Dependency Injection: Manages service creation and resource sharing seamlessly.
-
Twig Engine: Uses a fast, secure, and clear template syntax for views.
-
Doctrine ORM: Provides database abstraction to map records directly to PHP classes.
-
Symfony Flex: Automates package installation and configuration inside your app.
-
Developer Tools: Includes a web debug toolbar for performance monitoring.
Step-by-Step Practical Example
The following example demonstrates how to create a basic webpage using Symfony. The code maps a URL route to a controller method, which processes the request and returns an HTML view.
- 1. Setup a Project
Initialize a fresh framework directory via Composer using your terminal:
composer create-project symfony/skeleton my_project_name
cd my_project_name
composer require webapp
- 2. Create the Controller
Controllers contain the application logic. Write a file named LuckyController.php inside the src/Controller/ directory. PHP attributes are utilized directly above the method to set up the routing.
<?php
// src/Controller/LuckyController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class LuckyController extends AbstractController
{
#[Route('/lucky/number', name: 'app_lucky_number')]
public function number(): Response
{
$number = random_int(0, 100);
// Render the view template and pass variables to it
return $this->render('lucky/number.html.twig', [
'lucky_number' => $number,
]);
}
}
- 3. Create the View Template
Symfony relies on Twig for its frontend views. Save the file below inside your project directory at templates/lucky/number.html.twig:
{# templates/lucky/number.html.twig #}
<!DOCTYPE html>
<html>
<head>
<title>Your Lucky Number</title>
</head>
<body>
<h1>Your lucky number is: {{ lucky_number }}</h1>
<p>Refresh the webpage to generate a brand new number!</p>
</body>
</html>
- 4. Launch the Server
Launch the built-in development web server to run your site locally:
symfony serve
Use Doctrine ORM if you want to make database migrations easy.
Using Doctrine ORM in Symfony
To use Doctrine ORM in Symfony, you map PHP classes (entities) to database tables, manage data using the EntityManagerInterface, and fetch records through repository classes.
Below is a complete, step-by-step example of setting up and performing CRUD operations with a Product entity.
- 1. Install Dependencies & Configure Environment
First, install the Doctrine bundle and MakerBundle (used to generate code) via Composer:
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
Open your .env file at the project root and set up your DATABASE_URL:
# Example for MySQL
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/my_database?serverVersion=8.0"
Create the physical database using the Symfony CLI tool:
php bin/console doctrine:database:create
- 2. Create the Entity Class
Use Symfony's interactive wizard to create a Product entity. Run the command below and follow the prompts to add a name (string) and a price (integer/float):
php bin/console make:entity Product
This generates two main files: src/Entity/Product.php and src/Repository/ProductRepository.php.
The generated src/Entity/Product.php file uses modern PHP attributes for mapping:
<?php
namespace App\Entity;
use App\Repository\ProductRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\Column]
private ?float $price = null;
// Getters and Setters ...
public function getId(): ?int { return $this->id; }
public function getName(): ?string { return $this->name; }
public function setName(string $name): self { $this->name = $name; return $this; }
public function getPrice(): ?float { return $this->price; }
public function setPrice(float $price): self { $this->price = $price; return $this; }
}
- 3. Generate and Run Database Migrations
Generate a migration file that safely translates your PHP attributes into raw SQL statements:
php bin/console make:migration
Apply the migration schema directly to your connected database:
php bin/console doctrine:migrations:migrate
- 4. Create a Controller for CRUD Operations
Create a Controller to interact with the data. Use Dependency Injection to automatically pass Doctrine's EntityManagerInterface and your custom ProductRepository directly into your controller methods.
Create src/Controller/ProductController.php:
<?php
namespace App\Controller;
use App\Entity\Product;
use App\Repository\ProductRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
/**
* CREATE Example
*/
#[Route('/product/create', name: 'product_create')]
public function createProduct(EntityManagerInterface $entityManager): Response
{
// 1. Instantiate the PHP Object
$product = new Product();
$product->setName('Gaming Keyboard');
$product->setPrice(79.99);
// 2. Tell Doctrine you want to save this entity (no query is run yet)
$entityManager->persist($product);
// 3. Sync changes with the database (executes the INSERT query)
$entityManager->flush();
return new Response('Saved new product with id ' . $product->getId());
}
/**
* READ Example (Fetch all or single item)
*/
#[Route('/product/list', name: 'product_list')]
public function listProducts(ProductRepository $productRepository): Response
{
// Fetch all records using the Repository
$products = $productRepository->findAll();
// Or fetch a single item by specific criteria:
// $product = $productRepository->findOneBy(['name' => 'Gaming Keyboard']);
return $this->json($products);
}
/**
* UPDATE Example
*/
#[Route('/product/edit/{id}', name: 'product_edit')]
public function updateProduct(int $id, ProductRepository $productRepository, EntityManagerInterface $entityManager): Response
{
$product = $productRepository->find($id);
if (!$product) {
throw $this->createNotFoundException('No product found for id ' . $id);
}
// Make modifications to the object properties
$product->setPrice(69.99);
// persist() is not needed for existing entities already managed by Doctrine!
$entityManager->flush();
return $this->redirectToRoute('product_list');
}
/**
* DELETE Example
*/
#[Route('/product/delete/{id}', name: 'product_delete')]
public function deleteProduct(int $id, ProductRepository $productRepository, EntityManagerInterface $entityManager): Response
{
$product = $productRepository->find($id);
if ($product) {
// Schedule the entity deletion
$entityManager->remove($product);
$entityManager->flush();
}
return new Response('Product successfully deleted.');
}
}
Core Concepts to Remember
-
Entities (src/Entity/): Simple PHP data objects mapping to a single table database structure.
-
Repositories (src/Repository/): Classes used exclusively to retrieve data using read operations (find(), findAll(), findBy()).
-
EntityManager: The operational service engine used to save (persist()), update, or delete (remove()) tracked entities inside the database.
So easy, even an AI can do it!
Normally, doing all this by hand is just as fast for me.
Using the bin/console commands make starting a project from scratch fast and simple. Using Doctine ORM saves a lot of headaches when it comes to database migrations as it handles the heavy lifting for you when you deploy. When properly used, Symfony is extremely powerful.
Development Frameworks
JS Frameworks
CSS Frameworks
More Frameworks
Social Media
---
title: Symfony
text: The Symfony MVC Framework
image: /assets/svg/symfony1.svg
link:
target:
---