Nerds who love the symfony-project
27 Feb
In our team, we’ve been using Symfony since version 1.0, and ever since we started we’ve been evolving the way we work. For a little while I’ve been thinking of writing a “best practice” series, not to say this is the way you MUST do things, but to point out some of the things that have worked for us, and more than anything, to spark some conversation about what works for you.
It’s always best to start at the beginning, and for most Symfony (or any) web apps, this is often with designing your schema (ignoring requirements gathering, but who really cares what your users want :D)
Our approach here can be summed up in one word: Workbench. Ok maybe two: MySQL Workbench.
Yes this is only usefull for MySQL databases, but as our 2009 survey showed, this is far an away the most popular DB used with Symfony.
Maybe you really love writing your schema.yml and wouldn’t dream of doing it any other way, but personally, I find working with the visual representation of my schema to be a lot faster and generally delivers a much better result - there’s something about ’seeing’ it that makes it easier to design.
Apart from this (and some people I know genuinely prefer to write their schema file by hand) there are probably three more REALLY good reasons to give this a try:
Consistency
As I talked about here CaMeL cAsE matters. If you try and chop and change between a forward and reverse engineered DB/schema.yml you are almost guaranteed to run into trouble where someone has named something outside of the convention Symfony will use in a reverse engineer of the DB. Starting with and sticking to a process of reverse engineering your schema.yml (then model, forms & filters) from the DB will ensure consistency.
Upgrading
One of the seriously, seriously cool features of Workbench is that it can generate a MySQL ‘upgrade’ script for you. You can give it another Workbench file (eg: an older version of your schema) or a DB to connect to then compare it to your latest version and it will generate the ‘alter’ script for you to upgrade your DB. This is awesome for the real world where you don’t want to have to blow away and reload your database (leading to extra production downtime) if you don’t have to. In the case of an upgrade where only new tables or columns are added this becomes so simple it’s incredible. As some of you will know once your DB gets too big fixtures will no longer help you, in this case this is even more valuable.
Speed & Safety
Since Workbench allows you to connect to a MySQL server and ‘forward engineer’ (or reverse if you want it initially) you quickly realise the fastest as well as safest way to make schema changes to your app is really to do it in Workbench, forward engineer it to your DB, then rebuild your schema, model, forms & filters. The best processes in the world usually fail if they are hard to implement, but so far I’ve found doing things the right way has also been the easiest.
So, how do you go about designing your schema? Do you have a better method, or are you keen to give Workbench a workout?
7 Jan
I agree with this: Netbeans is a good IDE for Symfony development. I think this is especially true if you, like me, also develop with JVM languages. This last year I was doing some Java/Swing and Groovy projects, so I started using NetBeans again. It has a plugin for doing Symfony work - very handy.
(Off topic, the more I work with Groovy, the more I think this is the perfect language for PHP developers who want to learn a JVM language.)
4 Dec
This tip is a quick one for newbies. The Symfony book has some great tips as to when you would want to use a Symfony forward, vs a Symfony redirect. This quick post will show you the difference between the two and give you some guidelines to know when to use redirect or forward.
So what’s the main difference?
Symfony Redirect: This simply does a HTTP header(”location: “)
Symfony Forward: This is complete custom code that comes with the Symfony framework that forwards you within the Symfony application.
Use Symfony Forward if:
Use a Symfony Redirect if:
Conditional Forwarding/redirect
Quite often you need to forward or redirect if a condition has been met. Be sure to checkout the other Symfony functions that help you do this (forwardIf(), forwardUnless(), forward404If(), forward404Unless(), redirectIf(), and redirectUnless())
What about AJAX calls?
You can check if a HTTP request is an AJAX call before deciding what to do with it by calling calling $request->isXmlHttpRequest() in your actions class. Once you have done this you can choose what you want to do; redirect or forward.
8 Oct
I’ve been making some changes to an app that was using the Google Charts API to draw a couple of line and pie charts in a ‘reporting’ section. Sherif suggested while I was at it, I may as well look for some sexier charts, and a few Googles later came up with pChart. A quick look at their site will tell you it definitely fits the ’sexy’ criteria, and has some very cool features like caching (but who cares about, that main thing is it’s sexy
).
There are two ways to get pChart going with Symfony. Probably the easiest is to use xsPchartPlugin which was written specifically for the job and is as simple as running ./symfony plugin:install xsPChartPlugin within your app and creating and chmoding the web/images/tmp/xspchart/ directory it is configured to use.
xsPChartPlugin takes care of a few otherwise manual steps and includes some additional features like a function to clear the image directory. I think it’s a great plugin but I was just a little concerned I then had two things I’d have to keep up to date, the pChart lib and the plugin, or the plugin might fall behind and I’d have to remove it anyway.
Fortunately after installing xsPChartPlugin and seeing how it worked, I could now see easily how pChart would need to be installed for Symfony use, so here’s the steps for using it by itself:
./symfony cc to clear the cache and autoload the classes
// Dataset definition $DataSet = new pData; $DataSet->AddPoint(array(10,2,3,5,3),"Serie1"); $DataSet->AddPoint(array("January","February","March","April","May"),"Serie2"); $DataSet->AddAllSeries(); $DataSet->SetAbsciseLabelSerie("Serie2"); // Initialise the graph $Test = new pChart(420,250); $Test->drawFilledRoundedRectangle(7,7,413,243,5,240,240,240); $Test->drawRoundedRectangle(5,5,415,245,5,230,230,230); $Test->createColorGradientPalette(195,204,56,223,110,41,5); // Draw the pie chart $Test->setFontProperties("Fonts/tahoma.ttf",8); $Test->AntialiasQuality = 0; $Test->drawPieGraph($DataSet->GetData(),$DataSet->GetDataDescription(),180,130,110,PIE_PERCENTAGE_LABEL,FALSE,50,20,5); $Test->drawPieLegend(330,15,$DataSet->GetData(),$DataSet->GetDataDescription(),250,250,250); // Write the title $Test->setFontProperties("Fonts/MankSans.ttf",10); $Test->drawTitle(10,20,"Sales per month",100,100,100); $Test->Render("example10.png");
You don’t need to include the
// Standard inclusions include("pChart/pData.class"); include("pChart/pChart.class");
lines obviously as Symfony has taken care of that for us.
$Test->setFontProperties("Fonts/tahoma.ttf",8);
becomes (in both spots)
$Test->setFontProperties(sfConfig::get('sf_lib_dir')."/vendor/pChart-1.27d/Fonts/tahoma.ttf",8);
Then
$Test->Render("example10.png");
becomes
$Test->Render(sfConfig::get('sf_web_dir') . "/images/pchart/example1.png");
For the lazy people like me who just want something to cut and paste, the whole thing might look something like:
public function executeIndex(sfWebRequest $request) { // Dataset definition $DataSet = new pData; $DataSet->AddPoint(array(10,2,3,5,3),"Series1"); $DataSet->AddPoint(array("January","February","March","April","May"),"Series2"); $DataSet->AddAllSeries(); $DataSet->SetAbsciseLabelSerie("Series2"); // Initialise the graph $Test = new pChart(420,250); $Test->drawFilledRoundedRectangle(7,7,413,243,5,240,240,240); $Test->drawRoundedRectangle(5,5,415,245,5,230,230,230); $Test->createColorGradientPalette(195,204,56,223,110,41,5); // Draw the pie chart $Test->setFontProperties(sfConfig::get('sf_lib_dir')."/vendor/pChart-1.27d/Fonts/tahoma.ttf",8); $Test->AntialiasQuality = 0; $Test->drawPieGraph($DataSet->GetData(),$DataSet->GetDataDescription(),180,130,110,PIE_PERCENTAGE_LABEL,FALSE,50,20,5); $Test->drawPieLegend(330,15,$DataSet->GetData(),$DataSet->GetDataDescription(),250,250,250); // Write the title $Test->setFontProperties(sfConfig::get('sf_lib_dir')."/vendor/pChart-1.27d/Fonts/tahoma.ttf",12); $Test->drawTitle(10,20,"Sales per month",100,100,100); $Test->Render(sfConfig::get('sf_web_dir') . "/images/pchart/example1.png"); }
All that’s left to do now is show the image by using a normal image tag in your template:
echo image_tag('pchart/example1.png')
Now this post doesn’t show you how to use the pChart cache and a lot of other things, but it does get you up and running! It’s personal choice as to whether you want to use the plugin or do it by hand, but either way have fun with these sexy charts! ![]()
29 Sep
New Symfony Nerds Blogger! SymfonyNerds would like to welcome Lawrence to the team. Lawerence will be contributing to SymfonyNerds with updates from the world of Symfony. Here is his first blog below. If you are interested in contributing to SymfonyNerds, let one of us know!
My name is Lawrence. I am honored to be able to contribute to SymfonyNerds (my own blog is over here). I am mostly going to be contributing link round-ups, pointing to stories about Symfony that I find interesting.
First up, Doctrine is now the default ORM for Symfony (or rather, it will be starting in version 1.3):
Doctrine is now the default ORM for symfony. We still support Propel, of course, but recommend you start new projects with Doctrine.
I guess this news was expected for a long while (Jonathan Wage is the lead programmer on Doctrine, and he is also one of the core Symfony team), but now it is official.
One of the worst things about the Zend Framework is the way the caching is set up. You have to clear the cache after every change that you make. Symfony partially escapes that - using a dev front controller, you can see some of your changes, but you still need to run “symfony cc” when you change a Yaml file or add a new class that needs to be auto-loaded. Thankfully, that changes in 1.3:
A new autoloader has been added to the development environment that knows when changes are made, so you no longer have to run symfony cc after adding a new class.
It also sounds like a lot of the performance improvements that had originally been discussed for Symfony 2.0 are instead showing up in 1.3:
When we queried the community for feedback on what we should work on for symfony 1.3, performance was at the top of this list. We’ve taken this feedback to heart and have made significant improvements. A large portion of the routing system was rewritten to facilitate matching the incoming URL to a route much faster.
This is important. A competing framework ran some tests, according to which Symfony ranked as the absolute slowest. Speed is one issue where Symfony defitely needs to improve. (Noupe offers a balanced review of the most popular PHP frameworks, and says “[Symfony's] main downfall is that it is a bit slower than other frameworks.”
Ryan of That’s Quality is now working with Symfony on the Amazon Cloud and he says it is awesome:
As explained in part 1 of this series, the server you’ve instantiated acts as a static entity. Yes you can make all of the changes and customizations you want to it just like any other server. However, as soon as you shutdown that instance, all of those changes are lost forever. The solution is to save your server setup as an image (called an Amazon Machine Image or AMI), which can then be used later to instantiate new instances. This actualy forces you into the very responsible habit of always having an image of your exact server setup. From here you can very easily restart your instance or launch several identical servers and load balance between them.
I actually have my doubts about the Amazon Cloud. I’ve looked at Mosso and SliceHost and MediaTemple and they all seem simpler than Amazon’s Cloud. They offer virtual servers that feel like real servers, whereas Amazon’s services make you deal with the reality that there is nothing real about the offering. Possiby, as Ryan says, this forces good habits, but it is a pain to get started with. (And then there is the question of cost. My friend Chris Clarke jokes “Cloud computing is the future of hosting because the hosting companies are not making enough money off of standard hosting.” I rent a dedicated server from Hostway for just $99 a month, whereas Amazon’s basic setup is about $80 a month. So I would save $20 a month if I switch? Maybe. But I think my machine from Hostway has more capacity than the basic LAMP AMI I worked with this summer. Ryan mentions cost at the end of his article: “Above all else, clouds a hella-fun but expensive unless you really need to flex something.”)
Moving on to a different subject: I’ve been working on a site that allows for users to upload files and hold them privately, or share them. The files, of course, need to be stored out of the document root. I found this article by Timo Haberkern of Symfony Zone very helpful:
As we now use a Symfony-Controller you can do just use the complete Symfony infrastructure. You like to secure the PDF-files? Just enable the Symfony security mechanisms (is_secure: on in the security.yml) and only logged in users can download them. In the same way you can create paid content.
Finally, there was a conversation about memory usage and Symfony, over on the Symfony User Group, and Gareth McCumskey had this interesting remark:
One way to reduce your memory footprint is in the Propel criteria you use and the data returned. Propel’s hydration of returned data into objects can be quite high. We have actually used the Propel method doSelectRS (doSelectStmt in Propel 1.3) and selectively chosen which fields the query should return as well as then iterating through the result set ourselves and adding them to an array instead of having fully hydrated objects which can be memory hogs.
For small queries where the number of results returned is always going to be small, doSelect as is is great, but for large, unwieldy datasets its a better idea to use doSelectRS/doSelectStmt and then manage the results yourself.
10 Jul
This is a bit of a cop out of a post, but tonight I started looking for some info on Symfony & YUI… It’s something I’ve been meaning to look at for a long long time and while I was reading about CSS Frameworks I found out there is one that forms part of YUI, so it spurred me to look some more at it…
I found this great presentation I thought worth sharing by Dustin Whittle (from Yahoo!) about it here…
For those wanting to starting using it you should check out the main site linked to above and maybe check out the sfYUIPlugin, although it looks a little out of date.
Have a read. When I start playing around with it myself I’ll post what I learn…
20 Jun
Just a symfonynerds quick tip on getting a drop down select of names & URLs to submit when the userselects an item on it… One of those rare occasions when the first thing that came to mind seemed to work
<form action="<?php echo url_for('yesbar/submit') ?>" method="post">
<?php echo select_tag('links',objects_for_select($links, 'getLink', 'getName'), array("onchange" => "this.form.submit();")) ?>
</form>
19 Jun
The guys at UI Studio have done a really nice job of publishing http://symfony-check.org .
It’s a simple site that goes through and helps you check if your symfony application is ready for deploymen. Be sure it check it out.
14 Jun

Some interesting highlights:
1.0.* 18%
1.1.* 6%
1.2.* 76%
2.What ORM Layer do you use the most?
Propel 67%
Doctrine 31%
Don’t use ORM 0%
Other 2%
3. Where do you ask your Symfony questions?
People may select more than one checkbox, so percentages may add up to more than 100%.
Official Symfony Forums 65%
Symfony Blogs 23%
Symfony Users Google Group 40%
Symfony IRC Channel 19%
External Training / Consultant 2%
Other 14%
4. What environment do you run most of your Symfony applications on?
Red Hat Linux 6%
Ubuntu 39%
Windows Server 8%
Fedora 3%
CentOS 8%
Mac OS 7%
Other *nix 13%
Other 15%
5. How do you install Symfony?
Pear Install 34%
Source download 21%
SVN checkout 40%
SUSE package 0%
Debian/Ubuntu package 1%
Other 4%
Most popular “other” value: SVN:Externals
6. How long have you been developing Symfony applications for?
< 1 Year 29%
1 Year 23%
2 Years 21%
2+ Years 28%
7. What database do you use the most for your Symfony applications?
MySQL 88%
Oracle 0%
PostgreSQL 10%
MSSQL 0%
DB2 0%
SQLLite 2%
Other 0%
8. Have you (or do you) develop in other PHP Web Application Frameworks?
People may select more than one checkbox, so percentages may add up to more than 100%.
CakePHP 15%
Zend 30%
Seagull 1%
CodeIgniter 14%
eZ Components 3%
PRADO 2%
Seagull Project 0%
I have not developed in other frameworks 44%
Other 15%
Most popular “other” Smarty & “My Own”/”Custom Built” famework.
9. Largest Symfony application you have built is used by…
less than 50 Users 26%
less than 100 Users 6%
less than 500 Users 17%
less than 1,000 Users 8%
less than 2,000 Users 6%
greater than 2,000 Users 37%
10. What types of application do you mostly build with Symfony?
People may select more than one checkbox, so percentages may add up to more than 100%.
CRUD Applications 76%
SOA Based Apps (REST, SOAP…) 22%
Integrated applications (mashups with existing systems) 32%
Batch Processing Apps (Heaving focus on Tasks/Batch) 18%
Workflow applications 38%
eCommerce 29%
Other 10%
Popular responses for “other”: Online form-email, Intranets
11. What other popular libraries do you use with Symfony?
People may select more than one checkbox, so percentages may add up to more than 100%.
Prototype 41%
script.aculo.us 35%
jQuery 77%
jQuery UI 49%
YUI (Yahoo! UI) 12%
Adobe Flex 7%
Other 8%
Popular responses for “other”: ExtJS, MooTools & OpenLayers
12. How do you contribute to the Symfony project?
People may select more than one checkbox, so percentages may add up to more than 100%.
I use Symfony 94%
I am a Symfony Core Developer 3%
I report bugs 39%
I contribute to the symfony-developers group 12%
I answer Symfony questions (IRC, Groups, Forums…) 43%
I blog about Symfony 25%
I am a plugin developer 23%
I contribute to the Symfony Wiki 11%
I contribute to the Symfony code Snippets 8%
Other 5%
Popular responses for “other”: Word of mouth / Sharing experiences with others.
13. What IDE do you use when developing in Symfony?
Eclipse + PDT 34%
Eclipse 3%
NetBeans 18%
Komodo 2%
PHP Designer 0%
NuSphere PHPEd 2%
Zend Studio 10%
PHPEdit 0%
My favourite text editor (Vi, Notepad, EditPlus…) 16%
Other 15%
Popular responses for “other”: Aptana, Coda, Dreamweaver
14. Where do you develop Symfony projects from?
Asia 7%
Africa 2%
North America 14%
South America 6%
Europe 71%
Australia 2%
Antarctica 0%
15. If you had to choose one reason why you use Symfony, what would it be?
Rapid Application Development (Admin Generator…) 27%
Ease of use for front-end development (Ajax, Forms etc..) 9%
Scalable Framework 16%
Standards-based framework 24%
Project Documentation 16%
Quick to get started 4%
Online Community 4%
Training and Enterprise Support 0%
Backed by an organisation 1%
16. If you had to pick one area to improve the Symfony framework - what would it be?
Simplify the Framework 14%
Improve documentation 24%
Additional features to the framework 8%
Further work on the Admin Generator 13%
Interoperability with other frameworks 3%
Improved plugins 16%
Focus on scalability 15%
Other 6%
Popular responses for “other”:
- Lots of responses to stream line the Forms API (multiple ways of doing things), leading to confusion.
- Focus on performance
5 May
This is a quick tip that will hopefully save you some time. The sfFormExtraPlugin is an excellent plugin with lots of extra features to help you build your forms. This tip is regarding the sfWidgetFormJQueryDate widget. This Widget lets you create a jQuery date selector. Setting up this widget is simple, but not well documented. Here are the basic steps of getting this started in your project forms:
1. Install the sfFormExtraPlugin
./symfony symfony plugin:install sfFormExtraPlugin
2. Install relevant jQuery libraries:
a) Download jQuery AND
b) Download jQueryUI
3. Setup jQuery in your project
Extract the JavaScript libs to your project js folder, then modify your app view.yml to include them:
javascripts: [jquery-1.3.2.min.js, jquery-ui-1.7.1.custom.min.js]
Note: The order in which the jQuery libs are included are important and can cause a conflict if they are not in the order above.
4. Setup the CSS for jQuery UI
When you download the jQuery UI, extract the smoothness theme into your web css directory. IE:
/web/css/smoothness
Now include the relevant CSS in your app view.yml:
stylesheets: [main, smoothness/jquery-ui-1.7.1.custom.css]
5. Setup the Widget your form class:
Note in my example below, I will have an image icon as the date selector (/images/icons/calendar_view_month.gif). This is what the form class will look like:
class myForm extends sfForm { public function configure() { $this->setWidgets(array( 'from_date' => new sfWidgetFormJQueryDate(array( 'image'=>'/images/icons/calendar_view_month.gif', 'format' => '%day%/%month%/%year%') ), //...other widgets )); $this->widgetSchema->setLabels(array( 'from_date' => 'From Date', //...other labels )); } }
6. Display it in your view:
Action:
public function executeSearch(sfWebRequest $request){ $this->form = new myForm(); return sfView::SUCCESS; }
View:
.... echo $form['from_date']->renderLabel().":".$form['from_date']; ....
And that’s it! You should get something looking like this:

Hope this helps.