Directory Structure
The previous page listed the top-level folders — config/, src/,
templates/, public/, and var/. Here we go one level deeper
into src/ and config/ and look at why Symfony organizes things this way,
not just what the folders are called.
Inside src/: Controller, Entity, Repository
A default Symfony project splits your application code into three folders under src/
that work together on every database-backed page:
| Folder | Role |
|---|---|
src/Entity/ | Plain PHP classes that model one row of a database table — an Article entity models one article |
src/Repository/ | The query layer for one Entity — fetching, filtering, and searching Article rows lives in ArticleRepository |
src/Controller/ | Handles incoming requests and orchestrates the response — it asks a Repository for data, then hands it to a template |
In practice the flow is: a request hits a Controller, the Controller asks a Repository for the Entities it needs, and the Repository returns Entity objects built from database rows. Each layer has exactly one job.
config/packages/ and config/services.yaml
config/packages/ holds one configuration file per installed bundle — for example
config/packages/twig.yaml configures the Twig bundle, and
config/packages/doctrine.yaml configures Doctrine. Symfony Flex is what creates most
of these files automatically when you install a package, as covered on the previous page.
config/services.yaml is different: it's where your own services and any
manual container tweaks are configured, rather than a specific bundle's settings. Most of the
time Symfony's autowiring handles this for you without edits, but the file is there when you need
to be explicit.
.env and .env.local
Symfony reads environment configuration from .env files at the project root.
.env is committed to version control and holds sane defaults that work for every
developer on the team. .env.local is not committed — it's where each
developer overrides values for their own machine, most commonly the database connection string.
# .env (committed — safe defaults, no real secrets)
DATABASE_URL="mysql://app:app@127.0.0.1:3306/app_dev"
# .env.local (ignored by git — your machine's real values)
DATABASE_URL="mysql://root:secret@127.0.0.1:3306/my_project"
bin/console: The Command-Line Entry Point
Every Symfony CLI command you'll run from inside your project — clearing the cache, creating a
controller, running database migrations, or any custom command you write — goes through one
script: bin/console.
php bin/console cache:clear
php bin/console make:controller
We'll come back to bin/console in depth, including how to write your own commands,
on the Console Commands page later in this track.