Symfony2 Bundle Structure, a use case

(Written by Thomas Botton and Patrick Zahnd)

Symfony2 was released as Beta 1 few weeks ago. Since it starts to be our main PHP framework here at Liip, we decided to dive deeper into the core component of Symfony2: the bundles. Indeed, the structure of it needs to be clearly understood in order to have maintainable and sustainable code.

This blogpost aims to propose a project that one can take as a real life example for building its own bundle set with a correct structure – at least avoiding the main common mistakes.

In general, a bundle is meant to be a standalone component that can be reused and implemented by anyone in their project – as nobody wants to reinvent the wheel.
Bundles can have controllers, entities, forms, views, etc… To prevent these components to end up in a mess, Symfony2 comes with some rules and architecture to follow.

We recommend reading the Symfony2 “Bundle Directory Structure” post before starting at this point:

Full bundle structure


Used to expose commands to the console (app/console).


The place you put your controllers. You should separate Frontend and Backend controllers into subdirectories – if you have both – in order to have it more readable.


Here you can load your own services by creating a so-called Extension.


Mapping for ODM objects. For example Contact Messages which you send as an email.


Mappings for your ORM objects.


Form definitions.


Configuration of your project.


XML (or YML, or PHP) configuration files, like the routing.xml for example. Default is to use XML, and you have to use XML in Bundles you’d like to commit.


The templates in the format you prefer (PHP, Twig, …).


Translations file in XLIFF format.


Public files like images, CSS stylesheets and Javascript files.


Bundle functionality tests.

Sample project

As an example, we decided to go with a web application handling various music events and the user comments.
The following shows how to translate/divide a simple feature list within a set of bundles.

  • Events
    • Frontend
    • Event list
    • Search event
    • User can register for event
    • Backend
    • CRUD event over an admin interface and on the console
  • Visitor Echoes
    • Users can write a comment
  • Contact form
  • Pages displaying static content


Described in bundles

  • EventBundle
  • EchoBundle
  • ContactBundle
  • StaticBundle

Event bundle

The EventBundle encloses

  • commands to access the backend function
  • frontend and backend controllers
  • entity for the concerts
  • form to add concerts (backend)
  • form to register for an event (frontend)



The EchoBundle encloses

  • frontend controller
  • entity for the echoes
  • form to add an echo



The ContactBundle encloses

  • a frontend controller
  • contact form



You should not use this approach in production, this is just for example

The StaticBundle only encloses a frontend controller which will be responsible to take a page name as routing argument and then to display the corresponding template. If none is matching then 404 is displayed.



From this small case study, we can see some “bundle properties” drawing up which can be pick up depending on the bundle you are building:

  • Backend/Frontend differentiation: this structure allows you the get more readability and help you find faster what you want to work on, depending on if it is front or backend. This splitting usually occurs to the following directories: /Controller, /Ressources/views and /Tests
  • DB interaction based bundle (i.e. Entity/Document and Forms): that is the case for a lot of bundles which rely on one or more entities needing forms to interact with (create, modify or delete)
  • Customizable/Dependency Injection: this is the place where you can handle your own services. Therefore you have to create a so-called Extension. To understand that, you might want to read the following two blog posts: /

To sum up, we could say that the bundles’ goal is to split feature/functionality in order to be reusable as much as possible. If you end up with only one bundle for your web application, you might be wrong. Just get your head back from code and think: it must be a possibility to break your “SiteBundle” into at least 2 bundles. Else it means that you are having a static website, then you should go with a “StaticBundle”.

You advocate against a StaticBundle in production. So what would be your suggested approach when something like that is in fact needed?

Very important article.#Bookmarked#
Thank you, guys u saved my day.


You should at least do an abstraction for the pages. For example:

[Bundle directory]/Document/Page.php
[Bundle directory]/Document/PageManager.php

– The page defines the fields (here just $content).
– The page manager has the methods to get the content (or throw the exception).

You should also not save the pages as template files in the views directory.

I hope this was helpful.

How do you render or configure actions in routing, when they are placed in a subdirectory?

Found it, just use the backslash, like so:

I’m working with a neighbor who runs GMCSVT. They provide event services and currently have some asp pages to help them.

It’s a similar set of needs to what you have here. I started some prototyping in 2.0 and then went back to 1.4 which I’ve been using for the last year. Have you got much further with this project and would you consider sharing some of your findings/code? I been playing with an event Datatable showing the upcoming events and am working on a
Calendar view just now..


Unfortunately we didn’t (yet?) wrote such an application in Symfony2.
We took this use case for having real world example to base our blogpost on.

Nevertheless, the Symfony2 project has great documentation that we advice you to read through [1].
It should provide you most of the answers you need to complete your project.

We wish you all the best for your further development. Don’t hesitate to keep us updated with your results.


I’m newbie in Symfony2. I’m curious where to put classes like for example Cart in Webstore implementation. Can anyone dispel my doubts?

Hello @Kuba

Since “Cart” would probably be an entity, it goes into the “Entity” or “Document” folder in your Bundle.

If you have helper classes, then you can create separate folders within your Bundle to structure them. Therefore you can take the “Util” folder in the UserBundle as an example:

Thanks for this helpful post !

I’d like to know how you manage Documents here : Registration.php and Message.php ? Are they message templates (writen in PHP) or you stock it in no-sql db (like mongoDB) ?

Thanks ;-)

Hello @zawla

I am happy to hear our blog post was helpful. I guess this totally depends on the amount of signups you expect:

Only some per week: I would just send an email in this case – which you can format using a twig template. I would send it to myself/my client and a confirmation to the person who signs up.

Several every day: I would either save the message fileds into a SQL database or the formatted message into a nosql database. I would not send a message to myself/my client anymore but rather create a backend where you can find and manage the signups.

Lots of mails per day: I would probably add a queue system, which handles the sending of the signup mails.

Thank you @Patrick for your advise

Yes it’s helpful because the most tutorials I’ve read talk about ONE bundle (in this case we don’t take advantage of using symfony2 framework!)

What I don’t understand in this use case is the aim, reason behind adding such directory “Document” if we can format the Message using a twig template…

You are welcome @Zawla ;)

The aim of having the Document directory is, that you
– define what fields you need in the given “Documents”,
– define the field formats
– define the field validation
– and can generate a form from it directly.
Also it makes it easier to extend. If you for example want to save the given values to the database you can just extend the Document.

The folder you do not really have to name “Document”, this is just a proposal.

Great article. We were considering to switch Symfony2; and now I feel more confident about some important aspects & setups. Thanks.


More than three years after, is this structure still a good practice? Is it possible to easily scaffold it (create Frontend and Backend subdirectories, Routes, …) ?

Nothing much as changed since .. there is now the SensioGeneratorBundle to generate bundles.

semi related, the symfony best practices were recently released: