Introduction
Symfony is one of the most powerful and mature PHP frameworks. It is widely used for professional, enterprise, and long-term web applications.
However, for many PHP developers, Symfony can feel a little different at the beginning.
If you come from Laravel, custom PHP, or another framework, Symfony may look more explicit, more configuration-driven, and more structured. This can feel difficult at first, but once you understand how Symfony is organized, it becomes very predictable and clean.
This article explains Symfony from a PHP developer’s point of view. We will look at what Symfony really is, how a Symfony project is structured, and what the most important folders and files do.
By the end, you should have a clear mental model of how a Symfony application works.
What Is Symfony?
Symfony is a PHP framework, but it is also more than that.
Symfony is built from many reusable components. These components can be used inside Symfony applications, but they can also be used independently in other PHP projects.
Some well-known Symfony components include:
HttpFoundation
Routing
Console
DependencyInjection
EventDispatcher
Validator
Serializer
Mailer
Messenger
SecurityEach component solves a specific problem.
For example, the Console component helps build command-line tools. The Routing component helps match URLs to controllers. The DependencyInjection component helps manage services and dependencies.
This component-based design is one of Symfony’s biggest strengths.
Symfony Framework vs Symfony Components
It is important to understand the difference between Symfony Framework and Symfony Components.
Symfony Components are standalone PHP packages.
Symfony Framework is the full framework built using many of those components together.
This means Symfony is very modular. You can use the full framework for a complete web application, or you can use only some components in another project.
This is one reason Symfony has had such a strong influence on the PHP ecosystem.
Symfony Compared to Laravel
Laravel and Symfony are both popular PHP frameworks, but they feel different.
Laravel focuses heavily on developer experience and fast development. Many things are ready out of the box, and Laravel often gives developers a very smooth and expressive workflow.
Symfony is usually more explicit. It gives you strong structure, clear configuration, and powerful dependency injection.
A simple way to think about it is:
Laravel helps you move fast with elegant defaults.
Symfony helps you build explicit and highly configurable applications.This does not mean one is always better than the other. They simply have different styles.
For developers learning Symfony, the most important thing is to understand how Symfony organizes code and how requests flow through the application.
Creating a Symfony Project
A Symfony project can be created in different ways.
A minimal project can be created with:
symfony new my_projectThis creates a lightweight Symfony skeleton.
For a full web application, you can use:
symfony new my_project --webappThe web application version installs common packages used for traditional web development, such as Twig, Doctrine, Forms, and Security.
If you are learning Symfony as a full framework, the webapp option is usually easier because it gives you a more complete project structure.
Symfony Project Structure
A typical Symfony project looks like this:
your-project/
├── assets/
├── bin/
│ └── console
├── config/
├── migrations/
├── public/
│ └── index.php
├── src/
├── templates/
├── tests/
├── translations/
├── var/
│ ├── cache/
│ └── log/
├── vendor/
├── .env
├── composer.json
└── symfony.lockEach folder has a specific responsibility.
Understanding these folders is one of the first steps to becoming comfortable with Symfony.
The public Directory
The public directory is the web root of the application.
The most important file inside it is:
public/index.phpThis file is the front controller of the Symfony application.
Every HTTP request enters the application through this file. Symfony then boots the framework, matches the route, executes the controller, and returns a response.
The request flow looks like this:
Browser Request
↓
public/index.php
↓
Symfony Kernel
↓
Router
↓
Controller
↓
ResponseThis is similar to many modern PHP frameworks where all requests go through a single entry point.
The src Directory
The src directory contains the main application code.
This is where you usually write your controllers, services, entities, repositories, event subscribers, commands, and other application classes.
A common structure may look like this:
src/
├── Controller/
├── Entity/
├── Repository/
├── Service/
├── Form/
├── Security/
├── EventSubscriber/
└── Kernel.phpThe src directory is where most of your daily development work happens.
For example, a simple controller may look like this:
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HelloController
{
#[Route('/hello', name: 'hello')]
public function index(): Response
{
return new Response('Hello from Symfony');
}
}This example defines a route and returns a simple HTTP response.
The config Directory
The config directory contains Symfony configuration files.
A typical Symfony project includes:
config/
├── packages/
├── routes/
├── services.yaml
└── bundles.phpSymfony uses configuration heavily. This is one of the biggest differences developers notice when learning Symfony.
The services.yaml file is especially important because it controls how services are registered and autowired.
A common configuration looks like this:
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'This tells Symfony to automatically register many classes inside the src directory as services.
The templates Directory
The templates directory contains Twig templates.
Twig is Symfony’s default templating engine.
A basic template may look like this:
<h1>Hello {{ name }}</h1>A controller can render this template:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HomeController extends AbstractController
{
#[Route('/', name: 'home')]
public function index(): Response
{
return $this->render('home/index.html.twig', [
'name' => 'John',
]);
}
}Twig plays a similar role to Blade in Laravel, but it has its own syntax and conventions.
The var Directory
The var directory stores runtime files.
The most common subdirectories are:
var/cache/
var/log/Symfony stores cached files and logs here.
This directory should usually be writable by the web server. You normally do not edit files inside this directory manually.
The vendor Directory
The vendor directory contains Composer dependencies.
This is where Symfony packages and third-party PHP libraries are installed.
You should not write custom application code inside vendor.
Your application code belongs in src.
The bin/console Command
Symfony has a command-line tool located at:
bin/consoleYou use it like this:
php bin/consoleThis is similar in purpose to Laravel’s Artisan command.
Common Symfony commands include:
php bin/console cache:clear
php bin/console debug:router
php bin/console debug:container
php bin/console make:controller
php bin/console make:entity
php bin/console doctrine:migrations:migrateThe console is an important part of daily Symfony development.
What Is the Symfony Kernel?
The Symfony kernel is located in:
src/Kernel.phpThe kernel is responsible for booting the application.
It loads bundles, prepares configuration, builds the service container, and helps handle incoming requests.
Most developers do not edit the kernel often, but it is important to know that it is the central part of the Symfony application lifecycle.
What Are Bundles?
A bundle is like a package or module that adds functionality to Symfony.
Common bundles include:
FrameworkBundle
TwigBundle
DoctrineBundle
SecurityBundle
MakerBundleIn older Symfony applications, developers often created application-specific bundles. In modern Symfony projects, most application code is usually placed directly inside src.
Bundles are still important, but for normal application development, you usually do not need to create custom bundles.
A Simple Symfony Controller Example
Here is a very simple Symfony controller:
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HelloController
{
#[Route('/hello-symfony', name: 'hello_symfony')]
public function hello(): Response
{
return new Response('I am learning Symfony step by step.');
}
}This code defines a route at:
/hello-symfonyWhen a user visits that URL, Symfony executes the hello method and returns a response.
This simple example shows the basic Symfony request flow:
Route
↓
Controller
↓
ResponseSymfony Mental Model
The most important thing to understand is that Symfony follows a clear request-response flow.
A request enters through public/index.php.
Symfony boots the kernel.
The router finds the matching route.
The controller runs.
The controller may call services, repositories, forms, validators, or templates.
Finally, Symfony returns a response.
The flow looks like this:
Request
↓
Front Controller
↓
Kernel
↓
Router
↓
Controller
↓
Service Layer
↓
ResponseOnce you understand this flow, Symfony becomes much easier to learn.
Conclusion
Symfony can feel complex at first, but its structure is logical and consistent.
The most important folders to understand are:
src Application code
config Framework and package configuration
public Web root and front controller
templates Twig templates
var Cache and logs
vendor Composer dependencies
bin Console commandsSymfony is explicit, modular, and powerful. It gives developers a strong foundation for building serious PHP applications.
If you are a PHP developer learning Symfony, start by understanding the project structure and request flow. Once these basics are clear, topics like routing, controllers, services, Doctrine, forms, security, and testing become much easier to learn.