If you weren’t convinced by the first 5 reasons why Symfony rocks, you will certainly be today.
Symfony’s closest competitors are probably RoR or rolling your own framework. Using a pre-made framework instead of rolling your own has several advantages:
- Easy collaboration between coders, because of standardized approach
- A framework developed by many will include nice features which you wouldn’t bother to implement on your own
- You can outsource part of your development easily, or if you serve customers they receive a product their own developers can easily work on.
- Working in a framework not developed by you teaches you the practices of other developers (some of which might be good)
Lets see the final 5 reasons why Symfony rocks. My chosen 10 are just a small subset of the powerful capabilities of Symfony and I will link to all good blog posts covering this topic. (Current Symfony version as of writing is 1.0.7)
1 – Internationalization and Localization (i18n & L10n)
Symfony offers a really fantastic suite of internationalization tools. I suppose the fact that the creators are in France has something to do with it. The simple comment example of the last post actually gives us a nice start to show the possibilities. We will support these nice languages: (English, Dutch, Italian and Romanian – the last two thanks to my girlfriend).
As mentioned Symfony provides a full solution. For the basic translation needs Symfony uses a helper function with two underscores, as such: __(‘text which will be translated’). The text which needs to be translated can be exported to an XLIFF format using a plugin (Will be part of Symfony in 1.1.0) . For those wondering the XLIFF format looks like this:
<trans-unit id="5">
<source>Your name</source>
<target>Uw naam</target>
</trans-unit>
A simple config setting deals with the usage of utf-8; Formatting for numbers and dates are available and use the culture automatically. format_date() and format_number() automatically adjust their output depending on the culture.
Best of all the data model supports the concept of I18n tables. This allows you to have translations of items in your database (for instance products) and leave all the logic of dealing with this to Symfony. More advanced translation needs such as sentences, which depending on the database results need to be pluralized are also supported.
Lets look at the possibilities using the simple comment example. Implementing these languages is achieved in a few simple steps:
Firstly Symfony needs to be configured to support translations. This feature is turned off by default for performance reasons. To do this simply uncomment the commented lines in frontend/config/i18n.yml and set the following settings in frontend/config/settings.yml:
standard_helpers: [i18n]
charset: utf-8
i18n: on
Secondly we need to tell Symfony how to change the URLs, which we do in routing.yml. We will use URLs like this symfony-examples/nl/comment. Thirdly we need to actually use the interface translation helper __ on all our text, as such:
__('All Comments:')
I happened to forget the submit button the first time around. This is a rather tedious process and you would usually do this while you create the template and not afterwards.
So now the fun of actually translating. First we create the messages.ro.xml and run the command: symfony i18n extract frontend ro. This command uses the plugin to extract the text, which needs translating. After some translating we now have a nicely internationalized version of the comment example. Go see and click the flags!
Those cute flags were created by famfamfam
Read More: Internationalization in the Manual
2 – Caching
Caching is essential to the performance of any website. In many situations you can mess everything else up as long as your caching is good.
When reading about frameworks you will likely read that Symfony is somehow slow. Now off course you start to wonder whether this is true given that Yahoo uses it for its bookmark service. My impression is that these tests either use oversimplified ‘hello world’ examples or forget to query the database efficiently. A proper tests of speeds has to my knowledge not yet been conducted. Symfony is in fact lighting fast and offers a wide array of caching tools:
- Cache of an action (with or without the layout)
- Cache of a partial, a component, or a component slot
- Cache of a template fragment
- (plugin) sfArrayCachePlugin to cache an array
- (plugin) sfSuperCache Plugin to cache pages fully statically
- (snippet) Some work on a memcached plugin has already been done, which will be interesting for our developers fortunate enough to need it. (didn’t test this personally)
- Function result caching with sfFunctionCache
- sfProcessCache for memory caching with the help of PHP accelerators
In order to make the nice comment example nice and fast we will add some simple caching to it.
in myapplication/mymodule/config/cache.yml:
index:
enabled: on
with_layout: false
lifetime: 3600
This enables the cache, however we do want to clear the cache when someone submits a new comment. This is easily achieved by adding the following to your update action:
$sf_root_cache_dir = sfConfig::get('sf_root_cache_dir');
$cache_dir = $sf_root_cache_dir.'/frontend/*/template/*/all';
sfToolkit::clearGlob($cache_dir.'/*/*/comment.cache');
sfToolkit::clearGlob($cache_dir.'/*/comment.cache');
This looks a bit complicated, but these four lines of code deal with deleting the cache for all languages.
Read more: Caching in Symfony
Read more: Memcached
3 – Development environments
Environments are a great way of running a few different set of configurations next to each other. This comes in extremely handy for development. By default Symfony has two environments: production and development. In the later all the caching is disabled, errors are displayed and the WebDebug toolbar is available.
When I wanted to setup caching these environments came in very handy. Somehow my comment form was not updating as it should. To diagnose the situation I added another environment called test (accessible by frontend_test.php), similar to dev, but with caching enabled. It quickly became clear that the problem originated from caching, client side to be specific.
For every larger application you will need to keep track of these different sets of configurations and Symfony enables this with great ease. To access the various environments simply browse to the corresponding front controller (index.php for production, frontend_dev.php for development, frontend_test.php for testing.)
To set the configuration settings, simply specify the config files as follows (example from standard frontend/config/settings.yml):
all: .settings: escaping_strategy: both escaping_method: ESC_ENTITIES standard_helpers: [i18n, Partial] charset: utf-8 i18n: on cache: on prod: .settings: no_script_name: on dev: .settings: # E_ALL | E_STRICT = 4095 error_reporting: 4095 web_debug: on cache: off no_script_name: off etag: off test: .settings: # E_ALL | E_STRICT & ~E_NOTICE = 2047 error_reporting: 4095 cache: on web_debug: on no_script_name: off etag: on
Read more about: Development Environments
4 – Do not repeat yourself!
All coders live by the rule of not repeating yourself. Symfony tries to make this as easy as possible for you. This is completely integrated into all aspects of Symfony. You can for instance write your own: Propel Behaviors, Filters, Validators and pretty any piece of normal code. This is one of the things which you will really like in Symfony. As a starter and to keep it short I’ll just cover the DRY tools in the view layer.
In Symfony there are four important methods to not repeat yourself in the view layer:
- Partials
- Components
- Slots
- Component Slots
A partial is a simple piece of repeated template code. Say that you want to have the ability to add comments on multiple parts of your website. Simply stash the template code for adding comments in a partial. Partials are stored in the template directory with a _ (single underscore) before the partial name. When you want to include them simply use:
<?php include_partial('module/partial',array('varinpartial' => $myvar)) ?>
When the code to repeat becomes more complex and also requires some logic we can separate the logic and template code by using a component. Suppose for instance that you created a blog using Symfony and want to display the latest blog posts. The logic part of querying the database goes in a components.class.php file and the template in a partial. This gives you a very convenient way to reuse code. Including goes as follows:
<?php include_component('blog', 'latestposts') ?>
Slots are placeholders. You can define its content anywhere in the view layer. This is great if you for instance want to have a default sidebar in your layout, with the ability to overwrite it in the template.
The really interesting one is the component slot. This combines the power of the configuration file with logic and view separation. It functions very similar to a component, except that logic part to execute is indicated by a config file. As follows:
all:
components:
sidebar: [bar, user]
indexSuccess:
components:
sidebar: []
showSuccess:
components:
sidebar: [bar, options]
This would make the component slot display a user related sidebar by default, but on the index page display no sidebar and on the page displaying the user data display a sidebar with options.
Read more: Symfony’s View Layer
5 – Bridges to other frameworks
A short, but important point. Both the Zend framework and EZ components offer quite some valuable tools. Symfony feautures bridges to both of these, giving you access to two large arrays of tools.
This allows for nice things, such as an instant search engine for your site, using Zend Search Lucene (released just days ago). There is always a lot of discussion regarding the so called best framework, but I believe that eZComponents and Zend are actually pretty complimentary to Symfony.
These 10 points showed some of the power of Symfony. Hope you enjoyed them and will run over straight to The Symfony Documentation. If you like Symfony then Digg this post up and spread the word!
Mellow Morning » Ten reasons why Symfony rocks - Part 1 responded on 08 Sep 2007 at 8:05 pm #
[...] Update: Part 2 has been published: Ten Reasons why Symfony rocks – part 2 [...]
Myke responded on 09 Sep 2007 at 2:08 am #
There is already a plugin for using memcache as your caching layer.
http://trac.symfony-project.com/trac/wiki/sfMemcachePlugin
tschellenbach responded on 09 Sep 2007 at 9:10 am #
Very true, I had a look at that while writing, but then totally forgot about it. Good point!
halfer responded on 10 Sep 2007 at 2:14 pm #
Don’t forget that the yaml file for component configuration must be indented appropriately. It may be a browser issue, but on FF2 it looks like you have no indentation at all :o(
tschellenbach responded on 11 Sep 2007 at 6:53 am #
Very true, still had a bit of trouble with Wordpress. It is actually not too friendly for posting code, need to learn how to get it in control and leave my spaces alone.
Rob Roy responded on 12 Sep 2007 at 9:47 am #
A bit more on performance. At the recent Symfony Camp Fabien Potencier spoke at length about the major refactoring in progress for version 1.1 and 2.0. While he would only promise V2.0 “when it’s done”, he said he was expecting a 4 to 5 times performance increase for Symfony 2.0.
dgurba responded on 15 Sep 2007 at 4:10 am #
I’ll bite.
Wouldn’t symphony be rails competitor since rails came first? Since when does symphony lead the pack?
It just doesn’t rock as much.
I’d rather *write* this (and not use some generator): /ruby-on-rails/using-fragment -caching-in-rails/
#source:http://www.railsjitsu.com/blog
<%= article.content %>
Then this: /tutorial/1_0/my-first-project
# source: http://www.symfony-project.com
<?php echo $sf_data->getRaw(’sf_content’) ?>
The first is terse and to the point and I can maintain it easily … without language boilerplate syntax mucking up the works.
why does php recommend no short_tags … jsp, asp, php and rails use short tag religiously … please don’t make me type more.
superhaggis responded on 15 Sep 2007 at 9:26 am #
@dgurba
getRaw(’sf_content’) ?> is the placeholder for the entire template that is to be decorated with the application’s layout (see layout.php); would give you the value of the ‘content’ property for the ‘article’ object.
What you meant to say was getContent() ?>, which you would place in your template and setup via your action (using Symfony’s default ORM – Propel).
You clearly haven’t used Symfony if you are making fundamental mistakes like that, so you should refrain from passing comment on it until you do.
superhaggis responded on 15 Sep 2007 at 9:28 am #
The blog ate part of my reply – drop in your two code examples from Symfony and Rails.
rpsblog.com » A week of symfony #37 (10->16 September 2007) responded on 16 Sep 2007 at 10:53 pm #
[...] Ten reasons why Symfony rocks – Part 2 [...]
hardrock responded on 17 Sep 2007 at 8:20 am #
In response to dgurba:
Assuming that you have an object “article” with the property “content” (which was the case in your Rails example, but not in the symfony example) you would write just the very same in PHP:
#source: http://www.symfony-project.com/tutorial/1_0/my-first-project/content ?>
PHP offers this short syntax, although it may not be enabled on all configurations. And writing
content ?>
isn’t any longer, especially if you use code completion (which any good editor should have).
hardrock responded on 17 Sep 2007 at 8:22 am #
Apparently my code lines have been partly erased. That should have meant:
content ?>
and
content ?>
(dots indicating inexistant spaces)
tschellenbach responded on 17 Sep 2007 at 8:37 am #
Anyone know of a good plug in to fix Wordpress code handling behaviour for comments?
Mellow Morning » Introducing a cross site ajax plugin for Prototype responded on 07 Nov 2007 at 10:13 pm #
[...] Ajax was my main reason to choose the prototype framework. Furthermore it is also included in the great Symfony framework. In Prototype Ajax requests are written like [...]
scrivner responded on 06 Jun 2008 at 3:08 pm #
Nice reasons :D Symfony 1.0 Rocks! And Symfony 1.1 will rocks even more!
tschellenbach responded on 17 Jul 2008 at 8:19 am #
Fixed
Mellow Morning » Django vs Symfony responded on 28 Aug 2008 at 7:57 am #
[...] you can see from the posts (one, two) I’ve always been a big Symfony fan. Symfony is really great, but my current favourite is [...]
Daily Digest for 2008-08-28 | Pedro Trindade responded on 29 Aug 2008 at 7:59 am #
[...] Mellow Morning » Ten reasons why Symfony rocks – Part 2 [...]
Mike responded on 28 Sep 2008 at 1:16 pm #
Great article, thanks for sharing!
Kenneth van Rumste responded on 26 May 2009 at 9:33 am #
Any idea how it’s possible to get the i18n:extract to search class files too? In the Symfony, we still find: Unfortunately, the i18n:extract task does not yet parse form classes for untranslated strings. This is a huge problem… anyone an idea?