Image may be NSFW.
Clik here to view.Yesterday I attended the The State of Symfony 2 online conference. Actually my first online conference so it was quite exciting.
One of the most exciting questions though was: What is this new killer feature? Well, I made my guess before but lets see if I was right.
A few minutes before the first session there were already more than 100 people connected to the collaboration platform (http://www.elluminate.com/). Not a bad turnout for “just an online conference”.
The tool features moderation, listening as well as speaking, voting, a whiteboard, file transfers, a group chat and probably a lot more. It seemed a suitable choice.
Please excuse this article to be somewhat bullet-point-ish but I wrote most of it while listening to the sessions and I guess you will get the meaning anyway. Image may be NSFW.
Clik here to view.
Miscellaneous enhancements Fabien Potencier
The philosophy of Symfony 2 is to be as flexible as possible but with sensible defaults so it can be used right out of the box but possible to be changed to everything you need. Symfony 2 now also adapts PEAR standards to allow easy integration of non-symfony libraries rather than setting its own standards.
As much as possible went was put into the components to make sure they don’t depend on the MVC framework and can run standalone. This as well eases the use by Symfony newbies as well as experts.
Fabien introduced the latest additions to the components library.
- CssSelector developed from scratch converts CSS selector to their XPath equivalents.
- DomCrawler was based on symfony 1 browser class and can navigate the DOM. Its methods are chainable, it can utilise CssSelector but uses XPath internally and its API feels jQuery like.
- Browser is an HTTP client implemented in PHP that can even manage cookies.
- Finder is completely rewritten from its symfony 1 version and now implements PHPs Iterator interface. It’s chainable and provides easy to use date filters. The method signatures are standardised and instead of file handles it returns SplFileInfo instances. It can also work with streams like on the Zend FWs Amazon S3 Stream.
- HttpKernel is a framework construction kit and replaces the former RequestHandler. It has a very simple interface with only two methods getRequest() and handle(). It also includes a Profiler and the WebDebugToolbar functionalities.
All components are decoupled and therefore fully testable.
With these and the already known components Symfony 2 is not yet ready but the main concepts and overall philosophy will not change anymore.
From the Q&A at the end of the session we learned that at this point there will be no migration tool from symfony 1 to Symfony 2 but there will probably be an intermediate layer once Symfony 2 is ready.
However the API can change at any time! So for production use sf1.4 is still recommended!
The first alpha version planned for September.
Symfony 2 Meets Propel 1.5 François Zaninotto
I don’t really use Propel but still I was interested in its latest developments.
Propel 1.5 is fully backwards compatible with Propel 1.3 and 1.4. It’s faster, very IDE friendly, better documented, has three times more unit tests as Propel 1.3 and is fully integrated into symfony 1.4 using the sfPropel15Plugin.
Announced as one of the killer features come the model queries which are supposed to be to SQL what ActiveRecord is to the table row. To me it looked like a clone of Doctrines DQL but with domain specific method names..
Next killer feature and missing in Doctrine 1.2 is concrete table inheritance! But on the database level it is actually denormalised meaning that columns defined on the parent model are stored in the child tables as well for performance reasons. I wouldn’t really consider this to be concrete but composite and I remember having done something similar in Doctrine as well..
The third killer feature still to come will be the aggregate_column behaviour which utilises aggregation functions and stores and maintains their results in extra table columns.
Well, Propel is not dead but I am not convinced of its killer instinct and frankly I am annoyed by all this Doctrine bashing. If Propel is a good ORM (what it is to many users) then I should be able co-exist with other solutions! I think the major difference between Propel 1.5 and Doctrine 2 is that Propel is still an ActiveRecord which some might prefer. Not me though.
Funnily after the presentation a poll was setup whether to prefer Propel or Doctrine and when I had a look it was 76% favouring Doctrine. Image may be NSFW.
Clik here to view. http://twtpoll.com/r/545mw5. Nowhere near representative but entertaining.
What’s new in the Doctrine 2 Symfony Integration Jonathan Wage
Jonathans session didn’t bring too many news for you when you followed his talks and tweets regularly but it was a good and up to date wrap up of the current implementation.
Next to the DoctrineBundle for Symfony 2 there now is also a MondoDB Object Document Mapper bundle (ODM not ORM!) and a bundle for the beloved Doctrine Migrations with unchanged functionality.
Here’s Doctrines Architecture in a nutshell.
- The DBAL is responsible for managing connections and creating/dropping databases and running dql from the command line.
- The ORM has the EntitiyManager which persists and retrieves entities. You can have multiple instances (i.e. per database connection) of it.
- An Entity is a regular PHP object, no more magic, clean and testable, fast and only limited by PHP and now you can use the constructor as you like to.
One nice little thing I like is the new command line task that ensures your production settings! But also tasks for cache control are a nice addition.
DQL now uses a proper lexer/parser and has a strict BNF which allows for helpful syntax errors rather than side effects!
During development you can now change your schema without throwing away your database. Instead a schema update compares your current database layout and your current schema changes to update only what is necessary.
The MongoDB ODM shares the same architecture as ORM only with a DocumentManager instead of an EntitiyManager. Its DocumentManager makes full use of the MongoDB API.
You can even remap objects from Document to Entity and back during development and even during runtime. So fetching a model from the database and saving it to MongoDB should be possible.
Currently only MongoDB is supported and there is no support for CouchDB yet.
Finally Doctrines ORM supports class table inheritance but after seen the Propel version of it I have to take deeper look before I’m amazed. Image may be NSFW.
Clik here to view.
Unit & Functional Tests Fabien Potencier
Symfony 2 switched from lime to PHPUnit 3.5 because of standardisation (top prio as the framework is easier to learn that way). lime at the time was an easy option to PHP testing when unit testing had not yet arrived in the PHP world. By using PHPUnit Symfony can now benefit from yet another community while focussing on the framework and some improvements went back to PHPUnit already.
While this is great in itself it gets better when Fabien shares two best practices.
- There should be no more AllTests.php. Instead you can use phpunit.xml (it has a bootstrap attribute!).
Image may be NSFW.
Clik here to view.
- Don’t unit test your controllers! Controllers are not unit tested because they should only contain glue code and no business logic.
The functional test framework now has a cleaner API and utilises DomCrawler and Browser components.
Functional tests now only test the response object, which is exactly what you receive then the request is handled by your controller.
Image may be NSFW.
Clik here to view.
You can have multiple instances of the Browser so that you can even test the interaction of multiple clients. Even when you use a library with static states this will work as for each Browser a new PHP process will be created.
Image may be NSFW.
Clik here to view.
Because the functional tests are using the Browser component they can even be run on your production environment for monitoring purposes utilising the profiler of the request. Even testing of non-symfony websites is possible!
Image may be NSFW.
Clik here to view.
The new form framework Bernhard Schussek
After all the experience with the form framework of symfony 1 the new incarnation now got a whole new architecture and was completely redesigned for simplicity and reusability.
“Symfony 2 embraces your domain model”
Validators now validate domain models and forms.
Form fields are fully culture aware (localised) and can be grouped to “lightweight subforms” that become a widget like i.e. a google maps locator widget.
CollectionFields can be used to add lists of fields for 1-n relations.
Image may be NSFW.
Clik here to view.
The form framework is of course also a standalone library that does not depend on without Symfony 2.
Constraints can be added using annotations or XML or Yaml even using callbacks on your models so you can easily implement dynamic constraints.
Image may be NSFW.
Clik here to view.
If forms are now directly modelled on your domain objects then how can you do embedded forms? Well you can’t or at least not as you do in symfony 1. For example if you want to have a form for a user registration based on the user model but with additional fields for terms and conditions or newsletter subscriptions then you have to create a new model Registration first. This may seem like additional effort but if you think about it it makes a lot more sense.
Constraints can also be sequenced i.e. to save on resources when validating cheap constraints first before validating more costly ones that may contain a web service call.
HTML 5 input fields are not yet supported but the forms and validators and fields and everything is fully internationalisationable.
This sounds like something to really look forward to as the forms of symfony 1.2+ were certainly better than previous versions but had a lot of design flaws which make them feel unintuitive.
The Symfony 2 Killer Feature… Fabien Potencier
I was right! Image may be NSFW.
Clik here to view.
“Caching on the Edge”
According to yet another benchmark test Symfony 2 will be much faster than symfony 1 and even faster with more concurrent requests. All this is caused by the new killer feature: the cache.
Image may be NSFW.
Clik here to view.
Just like Varnish, Squid or Akamai Symfony 2 provides an HTTP cache or reverse proxy implemented in PHP. Symfony 2 also implements the related HTTP specifications and uses the cache headers for controlling the cache behaviour. This means that you can easily replace the PHP cache with Varnish or Akamai without the need to change.
And the cache classes are very easily integrated as they decorate the kernel. They can therefore be activated even for functional tests.
What about when parts of the page must be cached less?
Yes the best bit is still to come. Symfony 2 also implements the Edge Side Include (ESI) specifications written by Akamai which can be used to cache parts of the pages differently from the rest. This is accomplished by the view part of the MVC pattern which can return every partial separately if I understood correctly. You can even use other webpages as partials. Well, I have to digg into this at some point but I am utterly amazed of the completeness of the design.
I can see that it forces you to better separation of concerns as you have to think about your cache times early in the process. Which is good.
To sum it all up: the cache layer is separated from the framework. This does not only mean that you can exchange it with other reverse proxies it only means that for each page request that can be answered by the cache layer the kernel of the framework is not even booted! Symfony 2 also implements stale-while-revalidate and stale-if-error. Go and google it if you don’t know what this is, it is absolutely fantastic!
Another best practice advise:
If you have to think about invalidating the cache then you are most likely using expiration instead of validation. In other words: for dynamic parts you should let the cache validate the cache instead of setting an expire time. Cache validation is soon going to be automatically optimised. I’m curious how this will work.
However great this all sounds for now you have to remember that everything is still experimental.
Conclusion
Well what can I say except that Symfony 2 feels so right on so many levels. This might even have a big impact on the whole PHP community. Can’t wait until it’s stable in 2011!