I’ve now had the pleasure of developing two line of business applications using two very contrasting versions of the Symfony framework in PHP/MySQL. Whereas symfony 1.0 allowed you to generate custom CRUD (create, read, update and delete) interfaces by editing simple human-readable config files and overriding simple functions, new symfony 1.2 systems require you to understand badly documented APIs (more on that later), PHP’s OO programming quirks, the exact method call order of the new forms framework and write completely new classes to provide custom filter functionality. 1.1 was an interim version that left in backward compatibility.
Imagine you want to add a custom filter to the standard object lists that require custom joins or subselects on columns not in the object’s table. We want an extra filter called “is_missing_address”:
- Add “is_missing_address” and boolean type to the list in generator.yml
- Override the addFilterCriteria() method in the actions.php file to add the custom SQL when the “is_missing_address” filter is active
- Add “is_missing_address” to the filters list in generator.yml
- Add the sfWidgetFormChoice() Widget with all the select tag values to the list of Widgets in the Filters form class’s configure() method
- Add the sfValidatorChoice() class to the list of Validators
- Override the getValues() method of the filter form to include “is_missing_address” and a custom criteria method name
- Add a method such as addMissingAddressColumnCriteria() to the filter form class that adds the custom SQL
There are benefits to doing it the 1.2 way once you know what you are doing, but it is extremely complicated before you get your head around it. 1.0 was vastly more accessible partly in due to its amazing documentation.
I learnt symfony 1.0 by reading The Definitive Guide to symfony, written by the two lead developers. This was a fantastic book, detailed and simple. It was also clearly written (mainly by Francois Zaninotto) and obviously properly proofread before publishing.
The two lead developers have appeared to have a massive falling out after 1.0 was finished and massive changes brought in. The main author of the book has quit the project entirely after attempting to document the new changes and realising that 1.2 is only powerful and not simple. Simplicity and speed of development is probably the only two reasons anyone would want to use symfony in the first place (and probably PHP) – both of these points have been removed. The new documentation is full of French-lish such as “Softwares” and the homepage has what can only be described as non-native english. I believe parts of 1.0 were written with the documentation in mind (Documentation Driven Development), but 1.2 appears to have been made as powerful as possible, gaining maybe 10% more functionality at the expense of being easy to learn.
You do get what you pay for however, and symfony is free to use. I would not pay to use it when money gets you access to something like ASP.NET MVC now with fantastic MSDN documentation (there are free versions but it still requires a Windows server to host with). The symfony developers offer expensive training workshops – if the framework was still designed with simplicity in mind, you wouldn’t need training workshops or “symfony camps”.
The standard response to negative comments on open source projects appears to be “why don’t you volunteer to fix some bugs or correct some documentation?”. If I did that, it wouldn’t be free now would it?
At work I am currently tasked with redeveloping an intranet application used to track customers, products owned, support contracts, support records and all sorts of other CRM-esqué functions. The version used at the moment is a very fast Perl/MySQL/Mod_perl/Apache setup built over a few years. Its got to the point where the company needs more functionality and hacking extra functions into the current code is getting more and more difficult.
Why Symfony? Why PHP?
The current trend for “rich internet applications” is Ruby on Rails. Ruby has very powerful Object Role Modelling features that completely abstract the database from your code – no more writing SQL queries once the initial database has been set up. Database tables become class generators and rows become class references, free to be instantiated, updated and saved. Symfony is probably the closest PHP Framework to Ruby, as it utilises the Propel ORM layer (so can use almost any RDMS) and has a full Model View Controller structure. PHP runs on the vast majority of Apache installations and requires no extra software installed on the server – in addition finding skilled PHP programmers is far easier (although this might change). Symfony is also probably one of the most well documented Open Source web framework projects that I have come across, featuring a whole book written by a member of the community very close to the development team, an expansive Wiki on the project homepage and hundreds of plugins to simplify everything from AJAX to RSS feed generation.
Symfony can be used in two ways – through config files (text files defined using YAML, a simple markup language) which are passed to Generators to create the final scripts, or by manually coding the actions and pages. In reality, a combination of the two will be used. Tweaking the included Administration Generator will yield respectable results for the standard CRUD (Create, Read, Update, Delete) functions and it is extremely simple to create modules and actions with the included command-line tool that creates skeleton templates for you to use.
No longer do you have to plug in debugging tools (such as the Xdebug php extension) to get decent errors and stack traces when your application fails – Symfony provides a development view of your application that will output extremely useful information (such as execution time, a list of all SQL queries made and globals) right in the page outputted to your browser. Debugging the application I’ve been working has been as easy as that of a desktop app (coming from my experience of Visual Studio) – Symfony will work in conjunction with many PHP debugging extensions for further information if you need it (I haven’t).
Plus, Symfony is good enough for Yahoo to use it for a 20 Million user app, Yahoo Bookmarks!
I’ve been working alone for a month on the project and what strikes me is the huge amount of already achieved with no prior experience of Symfony:
- A complete database redesign using the excellent MySQL Workbench. Adding many-to-many relationships where there were none before requires a good deal of thought but the results when the ORM classes are generated by Propel in Symfony are well worth the effort
- Database migration handled by the CLI features of Symfony. One command will generate a .php file you can run at the command line (or cron job) with automatic access to all the features of your main application. Where the database had been vastly redesigned to support relationships, custom migration code had to be written (but where tables have not changed, you can copy table data directly in one line of manual SQL). The migration script takes about half an hour to run (approx. 3,000,000 records).
- User security and session support, timeouts etc
- Full creation and editing of all the major record types with administration control panels
- AJAX views and manipulation of information with per-user rearrangeable panels ala iGoogle
- Full filtering functions for searches with auto-paginated results (soon with Excel export)
- Global per-user filters that effect all searches
- …and lots of other actions specific to the application
Some advice to newcomers to Symfony from my experience:
- Don’t rewrite the wheel. Use the plugins available and tweak them if necessary.
- Use the Admin Generator, don’t fight it. Instead of writing custom create/edit/list actions when the Administration Generator does not meet your requirements (or altering the CSS won’t help), override templates with per-module versions of your own. Even better is creating a new Generator all together (although it is a headache writing PHP code that writes PHP code!) – check out the sfAdvancedAdminGenerator plugin for inspiration.
- Don’t worry too much about performance especially if your application is running a bit sluggish on your local machine. On a proper server with a production installation of Apache and MySQL, the application I thought was a bit slow flew given the chance. You can optimise later.
- Don’t be scared of upgrading – I went up a symfony version during production without a hitch and without a change in my code (from 1.0 to 1.1 this will be different)
- Use a decent IDE. I use PDT Eclipse and it definitely speeds up development. You will frequently have to edit several files at once so at least use a text editor with tabs.
- Read the book! I can’t stress this one enough. It is extremely well written and is available for free on the website.
I’ll post some more impressions and a brief postmortem when the project is finished.