Ehsan Bagherzadegan
Back to articles
10 min read

Symfony for PHP Developers: Understanding the Framework and Project Structure

Symfony can feel different from other PHP frameworks at first, especially for developers coming from Laravel or custom PHP projects. This beginner-friendly guide explains what Symfony is, how its project structure works, and how to understand the main folders and files in a Symfony application.

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
Security

Each 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_project

This creates a lightweight Symfony skeleton.

For a full web application, you can use:

symfony new my_project --webapp

The 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.lock

Each 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.php

This 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
    ↓
Response

This 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.php

The 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.php

Symfony 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/console

You use it like this:

php bin/console

This 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:migrate

The console is an important part of daily Symfony development.

What Is the Symfony Kernel?

The Symfony kernel is located in:

src/Kernel.php

The 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
MakerBundle

In 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-symfony

When 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
    ↓
Response

Symfony 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
    ↓
Response

Once 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 commands

Symfony 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.