Symfony2 is probably one of the most flexible PHP frameworks ever created. You can literally change everything. To allow such a level of customization and still keep things simple for the developer, Symfony2 relies on well-know design patterns, and best practices coming from the Java world. Of course, we have adapted those techniques to the PHP way of doing things, and the result is amazingly powerful.
Best of all, we have come up with optimization strategies that still make Symfony2 one of the fastest PHP framework.
The Symfony2 framework is based on a highly optimized micro-kernel. The Kernel is at the heart of the framework and it is responsible for both initializing your application configuration and bootstrapping the bundles.
A bundle is a structured set of files that implements a single feature and can be easily shared with other developers. In Symfony2, everything is a bundle, from the application you develop, to the features provided by the framework itself. Bundles easily hook into the configuration system to give to the developer a clean way to semantically configure and customize them.
Symfony2 is built on top of a lightweight and robust Dependency Injection Container, inspired by the Spring one. For a typical project, the developer doesn't interact with the container directly. All the implementation details are hidden behind a nice configuration system that allows everything to be customized via simple YAML or XML files or even via plain PHP code:
<web:templating escaping="htmlspecialchars" /> <doctrine:dbal driver="PDOMySql" dbname="dbname" username="root" password="" /> <swift:mailer transport="gmail" username="fabien.potencier" password="xxxxxxxx" />
web.templating: { escaping: htmlspecialchars }
doctrine.dbal: { driver: PDOMySql, dbname: dbname, username: root, password: ~ }
swift.mailer: { transport: gmail, username: fabien.potencier, password: xxxxxxxx }
The Request Handler is a flexible backbone for the HTTP request/response cycle. It takes the user request as an input and do its best to return a response.
It has no default assumption about where you store your controller, nor does it know how they are implemented. It's a glorified dispatcher that notifies events and expects that some listeners will take care of the hard work for it.
It means that Symfony2 is able to deliver highly-structured projects with a well-defined directory structure composed of configuration files (for the routing) and classes for the controllers:
hello:
pattern: /hello/:name
defaults: { _bundle: HelloBundle, _controller: Hello, _action: index }
namespace Bundle\HelloBundle\Controller; use Symfony\Framework\WebBundle\Controller; class HelloController extends Controller { public function indexAction($name) { return $this->createResponse('Hello '.$name); } }But Symfony2 can also adapt itself to the typical micro-framework style where everything is self-contained in a file:
$kernel->map(array( '/hello/:name' => function ($controller, $name) { return $controller->createResponse('Hello '.$name); }, ));
Your choice. Use the heavy-weight style for big projects where maintainability is a must, and switch to the micro-framework style for smaller projects.
The Kernel and the Request Handler are both based on the Event Dispatcher. It provides a lightweight implementation of the Observer design pattern. It is the best way to decouple your code and make it more flexible. The Symfony2 implementation is based on the Apple Cocoa notification center. But instead of being a straight port of the original implementation, the library has been rethought and redesigned to take into account the PHP platform specificities.
