Archives


Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Symfony hosting done right

ServerGrove, outstanding support at the right price for your Symfony hosting needs.
servergrove.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com

Fabien Potencier
The symfony 1.1 architecture
by Fabien Potencier – June 23, 2008 – 20 comments

The symfony 1.1 architecture

Before we release symfony 1.1 later this week, I want to give some information about the new symfony 1.1 architecture. Apart from the new exciting features we have in symfony 1.1, this version also represents a year of hard work to refactor the internals. Let's dig into symfony internals a bit!

The symfony platform

symfony 1.1 is based on a set of cohesive but decoupled classes, the symfony platform:

The symfony platform

Each class in the symfony platform is useable without the whole MVC architecture. The symfony platform classes have no dependency, and the only prerequisite to use them is the registration of the symfony autoloader:

require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
 

With just two lines of code, you can use any of the symfony platform classes. For example, if one of your projects does not use symfony, you can still use the sfYaml class by including the symfony autoloader:

require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
 
// load some YAML file or string
$config = sfYaml::load('/path/to/a/file.yml');
$config = sfYaml::load(<<<EOF
config:
  key: value
  foo: [bar, foobar]
  bar: { bar: foo }
EOF);
 
// dump some array to YAML
$yaml = sfYaml::dump($config);
 

The same goes for all classes, like the sfCache classes:

require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
 
$cache = new sfSQLiteCache(array('database' => dirname(__FILE__).'/cache.db'));
$cache->set('foo', 'bar');
$value = $cache->get('foo');
 

This example uses the SQLite backend but symfony also provides backends based on File, APC, XCache, EACcelerator, and Memcache.

Even if it seems natural to use those classes independently, the symfony platform goes one step further with classes like sfRequest or sfResponse. Let's see an example where we use these two classes to create a simple 'Hello World' script:

require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
 
$dispatcher = new sfEventDispatcher();
 
$request = new sfWebRequest($dispatcher);
$response = new sfWebResponse($dispatcher);
 
$content = 'Hello '.$request->getParameter('name', 'World');
 
$response->setContent($content);
$response->send();
 

In this example, we use a sfEventDispatcher object. Even if the platform classes are totally decoupled, some classes can communicate together thanks to the dispatcher. The dispatcher provides a mean to notify events and to listen to these events. You do not need to implement an interface to create a listener, nor use any specific base class to create an event; an event is only defined by its name and by the array of parameters sent by the notifier.

For example, the sfPatternRouting class listens to the request.filter_parameters event:

$callback = array($this, 'filterParameters');
$dispatcher->connect('request.filter_parameters', $callback);
 

And when a request is created, the sfWebRequest notifies the request.filter_parameters event:

$event = new sfEvent($this, 'request.filter_parameters');
$parameters = $dispatcher->filter($event, $parameters);
 

So, even if the sfWebRequest class and the sfPatternRouting class are decoupled, they automagically communicate together when they share the same dispatcher.

To illustrate this feature, let's change the previous example a bit by adding a routing object that connects the /hello/:name pattern to the 'Hello World' application:

require_once '/path/to/sfCoreAutoload.class.php';
sfCoreAutoload::register();
 
$dispatcher = new sfEventDispatcher();
 
$routing = new sfPatternRouting($dispatcher);
$routing->connect('hello', '/hello/:name');
 
$request = new sfWebRequest($dispatcher);
$response = new sfWebResponse($dispatcher);
 
$content = 'Hello '.$request->getParameter('name', 'World');
 
$response->setContent($content);
$response->send();
 

Now, if you save this script as index.php under the web root directory, you can access the application by typing something like /index.php/hello/Fabien in your browser.

This is great if you want to leverage some of the cool features symfony provides, without using the whole MVC architecture.

This is also a great way to migrate your old applications to symfony. Instead of rewriting your applications from scratch, you can introduce symfony concepts one at a time.

You can also create your very own framework on top of the symfony platform. You do not need to reinvent the wheel, the symfony platform has all you need to create a great framework:

  • sfRequest/sfRouting: The request
  • sfUser/sfStorage: The user/session
  • sfForm: The form framework
  • sfCache: The cache framework
  • sfOutputEscaper: The XSS protection layer
  • sfResponse: The response
  • ...

Of course, the symfony framework itself is powered by the symfony platform:

The symfony MVC framework

The sfConfiguration class provides a way to configure and to customize your applications. The sfContext class acts as a registry that holds references to all core objects. And thanks to the factories.yml configuration file, you can customize all the registry classes very easily, just by editing a YAML file.

The symfony MVC framework is provided by a set of additional classes on top of the symfony framework as shown below:

The symfony MVC framework

The Model layer is provided by third-party libraries, Propel or Doctrine. Even if symfony 1.1 is bundled with the Propel plugin, it's very easy to switch to Doctrine by installing the sfDoctrinePlugin. Both ORMs provide the same level of integration with symfony.

The View layer is provided by the sfView class, a bunch of helpers, and templates written by the developer.

The Controller layer is based on a filter chain and actions defined by the developer.

As of version 1.1, symfony is one of the most decoupled framework available in PHP, even more than the Zend Framework. For example, the sfForm framework is useable without any of the MVC classes whereas Zend_Form is somewhat tied to the controller and the view layers.

Comments RSS

  • gravatar
    #1 Artur Martins said on the 2008/06/23 at 16:37
    Wow... Excelent work guys!
  • gravatar
    #2 Markus said on the 2008/06/23 at 16:41
    little typo in the very first hello world example

    $disptacher has to be $dispatcher
  • gravatar
    #3 Olivier Mansour said on the 2008/06/23 at 17:18
    congrats for all this work. This note show well all the work done and how it seems exciting to work with symfony 1.1.
  • gravatar
    #4 Paolovas said on the 2008/06/23 at 17:50
    Good Job !
  • gravatar
    #5 Taku said on the 2008/06/23 at 18:40
    Great news to see technical stuff released ! Hope to see even more in the coming weeks :)

    Thanks a lot.
  • gravatar
    #6 Gummy said on the 2008/06/23 at 18:57
    Holly shit, this is a fucking awesome post. Now I can say that I understand clearly how works my everyday weapon of choice.
  • gravatar
    #7 Frank Stelzer said on the 2008/06/23 at 22:11
    Excellent, documentation sheet about symfony 1.1. Things getting so much clearer, after reading this article. Like always, great job!
  • gravatar
    #8 Akira said on the 2008/06/24 at 00:05
    Cool! :D
    Symfony is becoming a meta-framework. I'm expecting to see other teams grabbing your classes to extend their frameworks. It'll be good for the symfony community!
  • gravatar
    #9 Sebastien said on the 2008/06/24 at 10:30
    great works but something goes wrong for me:

    when i read "With just two lines of code, you can use any of the symfony platform classes. For example, if one of your projects does not use symfony, you can still use the sfYaml class by including the symfony autoloader:"
    i understand that i only need sfCoreAutoload in my project to use sfYaml, but when i read the sfCoreAutoload code i see sfException and sfFinder are used and in sfException i see it use sfConfig and sfYaml (sfContext is tested for existant then no dependencies ) it is a bit more than just one class :)

    perhaps i have miss something.
  • gravatar
    #10 z01d said on the 2008/06/24 at 10:35
    Hey, guys, that's great, but we'll probably need some tutorials (much like Askeet did for v.1) to showcase the benefits of the new (more complex) system to the end user (your average php coder).
  • gravatar
    #11 Mark said on the 2008/06/24 at 11:13
    Great work guys, I'm looking forward to using it.

    I was thinking that with such massive changes to the architecture, would it be more appropriate to give it a new major version number? Version 2.0 would be a better indication of how much it has changed. Calling it version 1.1 pretends only a few new features have changed (at least, following 'usual' versioning conventions...)
  • gravatar
    #12 NiKo said on the 2008/06/24 at 17:16
    Sebastien> You can of course just require_once the sfYaml class (and maybe the sfYamlDumper one) and use them as is in your non-symfony php project (exceptions used in these classes are the standard SPL ones).
  • gravatar
    #13 sebastien said on the 2008/06/24 at 19:15
    niko > désolé je parle trop mal anglais, ce qe je voulais dire c'est que quand on lit le diagramme on a l'impression que sfCoreAutoload est le minimum vital nécessaire pour utilisé des classes de la platform symfony alors que c'est un petit groupe composé de sfCoreAutoload, sfFinder, sfException,sfYaml, sfConfig d'apres ce que j'ai vu du code.

  • gravatar
    #14 mdesign said on the 2008/06/24 at 20:56
    mistake:
    article source code: $routing->connect('hello', '/hello/name');

    working code: $routing->connect('hello', '/hello/:name');

    Great, evolving framework!
    I hope the new book, and the form book will have the same quality like this post! except mistyping:)
  • gravatar
    #15 Aliakhtar said on the 2008/06/25 at 06:15
    Excellent work !

    This will really help us in understanding the whole framework.

    Thanks a lot.
  • gravatar
    #16 moreilla said on the 2008/06/25 at 09:06
    Symfony is the best framework because of its EXCELLENT documentation~Thank you~
  • gravatar
    #17 bqbtoan said on the 2008/06/25 at 18:58
    Cool :D, good Job!
  • gravatar
    #18 Jonathan Nieto said on the 2008/06/25 at 23:57
    Simply awesome!, great work
  • gravatar
    #19 Sebastian said on the 2008/07/02 at 22:41
    Excellent! The modularized architecture actually eliminates my only major concern with Symfony.
    Bye, bye, Zend Framework :)
  • gravatar
    #20 slantedview said on the 2008/07/18 at 18:40
    I just discovered symfony yesterday, and I'm already so impressed that I decided to rewrite my entire site (currently built with drupal) using symfony. I might be crazy, but I can't help it. This framework looks great!