Nerds who love the symfony-project
23 Dec
I’ve been thinking about the fact that the engineers at Google view static classes as terrible things. My own code has an unfortunate number of static classes. Mostly this is because I am not sure where to put some of the code. For instance, on every project I have a few methods that format output. Some of these methods are the same on every project, so I hate to put them in the action code. Where else? Output formatting obviously does not belong in the model classes. What about methods for formatting dates, methods which I use in action code in multiple modules? It is easiest to put this into a class of static methods. Then I can call it from everywhere.
Another approach would be to add methods to the parent class. The parent of all action classes is sfActions. I’ve thought about editing sfActions, but I hate the idea of editing a core class of Symfony. I’ve also thought about creating a child class of sfActions, adding my methods there, and then having all of my action classes inherit from that. This is probably the best way to go, but I admit to a certain laziness. At some point I plan to write my own custom generation classes, which would make this easier. For now I tend to rely on the auto-generate code. Also, there are some good arguments against tall object trees. In his book Effective Java, Joshua Bloch suggests “Favor composition over inheritance.”
Given these concerns, I was interested to read this article about worker classes in Symfony. They list these advantages:
Advantages of worker classes
1. actions could be shrinked huge in size
2. worker classes are more decoupled from the rest of symfony and could be tested better
3. you can replace the content of an worker method without breaking actions
This is a step away from the problems of static classes. It provides a place in the object hierarchy where this code might legitimately belong. The engineers at Google suggested that most static methods should really belong to one of their own parameters. I can imagine worker classes as a way of making this happening, without bloating up the owning class.
A follow-up article looks at the interface changes that worker classes allow. These changes should allow better long-term maintainability and better testing. I especially like the idea of removing all ORM specific code from my action classes.
The action (or template) does not process anymore with a concrete ORM model. With the help of the proxy class, we can change the underlying model layer without breaking anything in the action. By providing a well defined interface, the proxy class manages how a model could be modified and accessed.
At this point, you should understand the reason for all those changes. It may look like a huge overhead for just retrieving some data out of the model. But in our case it was a precondition for our global architecture.
Our models and our main business logic is partly served by and processed in SOA applications (there we use Propel and i hope in some near days also Doctrine). I implemented a mechanism, which allows worker classes to access those SOA applications very easily. They are fetching the serialized data from those applications, hydrate them into proxy classes and provide them to the rest of the project.
…In this way, action code is really short, it is completely decoupled from the logic how the model is originally handled and it works quite well. If we decide to change something in our architecture some day, we only have to change our worker and proxy classes. The rest of the project will not notice those changes, as it should be in a layered architecture.
Sure, this step is nothing for small applications. But when your project grows and grows, the number of requests in a second turns from dozens to hundreds, then you’ll be thankful, if your project provides this approach.
I will probably be adopting some of this technique for my own current project.
27 Nov
Just a quick post to make sure everyone is aware of the 1.3 and 1.4 documentation which is now out.
As well as the reference guides you should definitely check out the other stuff on that page including:
Well worth spending some time checkout out!
16 Nov
Drupal has become the most sophisticated piece of PHP software that non-PHP programmers are aware of. Therefore, increasingly, when decision makers are comparing technologies, Drupal is the one they use as their PHP reference. Consider this line from Sam Ruby (who is a brilliant technologist, but who does not know much about the world of PHP):
But the more interesting trend is that the language choice itself is no longer as primary as it once was, the real choices are increasingly drupal, django, and rails, with the language being a consequence of that choice.
He is comparing a framework (Django) to a CMS (Drupal). Obviously PHP looks bad when that kind of comparison is made. Ideally, the comparison would always be between a framework like Django and a framework like Symfony. But I get the impression that PHP frameworks are almost unknown outside of the world of PHP. Wait, I’ll amend that, even in the world of PHP, almost no one has ever heard of Symfony. Yesterday I was at WordCamp, New York, 2009, and no one that I spoke to had ever heard of Symfony.
Birdhouse offers another example of Django versus Drupal:
Every web shop has its favorite tools and languages. Settling on just a few keeps toolchains, deployment, and development workflows sane. At both the UC Berkeley Graduate School of Journalism and the Knight Digital Media Center, we’ve settled on a mix of:
WordPress for basic sites and “modest” online publications
Django for sites with more complex needs or non-standard data models
For example, it makes sense to build student magazines, handbooks, FAQs, and blogs with WordPress. But it’s simply not possible to build an equipment checkout system, or a course evaluation system, or a student/faculty/staff directory with WordPress — not while trying to preserve your sanity anyway. That’s because WordPress assumes so much about the structure of your data — it thinks every piece of content has a title, a summary, an author, etc. Start to veer away from that basic data structure and you find yourself quickly needing a platform that doesn’t make assumptions about how things should be done. For those kinds of problems, we use Django.
…To be clear on terms:
WordPress is a simple content management system.
Drupal is an advanced content management system.
Django is a framework.
At no point is a PHP framework compared to Django. Instead, Drupal is used and loses almost every comparison:
Object Orientation:
Python (the language on which Django is built) is extremely object-oriented, and thus so is Django. This means that data objects, querysets, variables, templates and arguments can be passed around in the codebase easily….
Drupal is not object-oriented.
Templating System
Django is famed for its super-clean, inheritance-based templating system, which makes it almost trivially easy to nest templates within templates, use different templates for different parts of the site, and to completely eliminate any redundancy in template code….
In contrast, a common complaint about Drupal is that templates can be difficult to customize. In fact, there are entire books about working with templates in Drupal.
Performance:
…Bruno Desthuilliers: I recently had to work on a not-so-complex (functionaly-wise) Durpal project, and the response times on my local station – all caches disabled of course – turned the development process into a sluggish nightmare. Never had this kind of problems with Django, even for far more complex apps.
Then there are some responses from other developers:
Preston Holmes: What happens is that non-developer/technical decision makers will evaluate Drupal and think that all their needs will be met out of the box. When they find out they aren’t, they need to hire developers, and then those developers have to massage existing modules to customize and tweak. Then at some point they have this monster of hodgepodge code. But its that entry point that is the key to Drupal’s popularity. … I don’t think people appreciate how much Drupal development is spawned by this existence of a usable entry point for Drupal by non- developers. (and that it has 1-click installs on hosts, and in general uses the far more common infrastructure of PHP-MySQL).
I get why Drupal is the point of comparison that most non-PHP people use to reference PHP. Jacob Coby pointed me to this comparison on Google Trends. Clearly, Drupal is way, way ahead of the PHP frameworks. The situation here is very different than the world of web development using, say, Ruby, where the usage of CMSes is dwarfed by the framework everyone uses to do Ruby web development.
I’m not sure what the answer to this is. Symfony can not even lose these comparisons, let alone win them, until more people have heard of it, and the comparison of technologies becomes more of framework versus framework, which would be more fair than the current framework versus CMS comparisons. (When the Django versus Symfony comparison is made, Symfony is at least able to hold its own, with at least a few areas where it is superior to Django) More so, as I meant to imply with the title of this post, I believe there is a self-reinforcing dynamic at work. The more frequently that the Python versus PHP (or Ruby versus PHP) comparison consists of comparing a framework to a CMS, the more reinforcement is given to the idea that PHP can be used to build CMSs, but not necessarily the kind of complicated software for which one would naturally prefer a framework. In this regard, I think the prominence of Drupal is actually doing harm to the growth of the PHP frameworks.
How to break this cycle? Possibly some sort of killer app, built around Symfony, would afford an easy point of reference for the public, but I’d have thought Yahoo Bookmarks and Daily Motion would have offered us that, and yet, so far, Symfony still lacks mindshare, even among technically savvy people.
I’d be curious to hear, in the comments below, people’s ideas for promoting Symfony.
9 Nov
The engineers at Google have posted a list of what they consider to be bad coding practices. Reading it over, I was struck by how many of the violations are common in Symfony code. (Please note, the tone of the article is sarcastic, so they are saying the opposite of what they mean.)
Make Your Own Dependencies - Instantiate objects using new in the middle of methods, don’t pass the object in. This is evil because whenever you new up an object inside a block of code and then use it, anyone that wants to test that code is also forced to use that concrete object you new’ed up. They can’t “inject” a dummy, fake, or other mock in to simplify the behavior or make assertions about what you do to it.
Depend on Large Context Objects - Pass around ginormous context objects (or small ones with hard to construct contents). These will reduce the clarity of methods [myMethod(Context ctx) is less clear than myMethod(User user, Label label)]. For testing, the context objects will need to be created, populated, and passed around.
In most of the form, model and action code that I’ve written, and that I’ve seen others write, it is common to instantiate new objects in the middle of methods. The code in Symfony tends to become all about the side effects, not about the return values of the methods. Functional purists would no doubt want to dynamite the whole project, if they saw some typical Symfony code. One of the authors of the post, Miško Hevery, writes on his blog:
Every time I see Law of Demeter violation I imagine a haystack where the code is desperately trying to locate the needle.
class Mechanic {
Engine engine;
Mechanic(Context context) {
this.engine = context.getEngine();
}
}The Mechanic does not care for the Context. You can tell because Mechanic does not store the reference to Context. Instead the Mechanic traverses the Context and looks for what it really needs, the Engine.
Hevery feels that the above code should be re-written so that the dependencies are injected:
class Mechanic {
Engine engine;
Mechanic(Engine engine) {
this.engine = engine;
}
}
This is one issue where Symfony is going to see big improvements soon. Fabien Potencier (the lead programmer of the Symfony framework) has written extensively on his own blog about a container for dependency management, which will be included in Symfony 2.0.
It is now time to dive into the Symfony 2 service container implementation.
The Dependency Injection Container in Symfony is managed by a class named sfServiceContainer. It is a very lightweight class that implements the basic features we talked about in the last article.
The Symfony Service Container is available as a standalone component in the symfony official Subversion repository: http://svn.symfony-project.com/components/dependency_injection/trunk/. Keep in mind that this component is still under heavy development, which means that things can change.
In Symfony speak, a service is any object managed by the container.
…[Because] the Container class extends the sfServiceContainer class, we can enjoy a cleaner interface.
Hevery is especially critical of the kind of code that involves multi-level reaching into other objects (a style of coding that I have seen on most of the Symfony projects that I’ve worked on):
class Monitor {
SparkPlug sparkPlug;
Monitor(Context context) {
this.sparkPlug = context.
getCar().getEngine().getPiston().getSparkPlug();
}
}
Formally, the principle of software design that Hevery is promoting is known as the Law Of Demeter:
The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).
…When applied to object-oriented programs, the Law of Demeter can be more precisely called the “Law of Demeter for Functions/Methods” (LoD-F). In this case, an object A can request a service (call a method) of an object instance B, but object A cannot “reach through” object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B’s internal structure. Instead, B’s class should be modified if necessary so that object A can simply make the request directly of object B, and then let object B propagate the request to any relevant subcomponents. Or A should have a direct reference to object C and make the call directly. If the law is followed, only object B knows its own internal structure.
Most of the Symfony projects I’ve worked on are rife with lines of code like this (in the actions):
$this->getUser()->getGuardUser()->getProfile()->getEmail()
To conform to the above ideals (The Law Of Demeter) the code should be re-written as:
$this->getUser()->getEmail()
In other words, the MyUser class should have a method that takes care of fetching the email for you. This way your action class does not get wedded (highly-coupled) to the fact that the MyUser class has a sfGuardUser object which contains a profile object which has a method for fetching email. Instead, the MyUser class hides the mechanics (decouples) the action class from the details of what classes possess the email address. Your action classes can use one of their member objects (the MyUser object) to fetch the email address, but the details of how this email address is fetched is left to other classes to figure out. There are 2 advantages here:
1.) The code is easier to test.
2.) If at some point you feel the need to completely refactor the code that handles your user information, you do not have to hunt through your code and change the dozens of lines where you’ve fetched the email address. Instead, you only have to make sure that the method getEmail() in the class MyUser still knows how to get the email. It is easier to change that one method than to hunt down and change a few dozens lines like this:
$this->getUser()->getGuardUser()->getProfile()->getEmail()
This issue is especially relevant to me right now, because I’m re-doing a Symfony site that was created by a bunch of other programmers. I notice the original programmers wrote a lot of code like this:
foreach($form->getFormFieldSchema()->getWidget()->getFields() as $key => $object)
{
$label = $form->getFormFieldSchema()->offsetGet($key)->renderLabelName();
if(isset($validatorSchema[$key]) and $validatorSchema[$key]->getOption(’required’) == true) {
$label .= ‘getFormFormatter()->translate($title) . ‘”>’ . $symbol . ‘‘;
}
$widgetSchema->setLabel($key, $label);
}
Perhaps the fault here is with the core Symfony team. The ideal of “loose coupling” suggests that the form objects should have a getFields method:
$form->getFields()
Perhaps such a convenience method should be auto-generated?
The core Symfony team can be faulted for promoting the above questionable practices. For instance, on the readme page for the sfGuardUserPlugin, this example is given:
$this->getUser()->getGuardUser()->getProfile()->getFirstName()
// or via the proxy method
$this->getUser()->getProfile()->getFirstName()
You’ll note that even the proxy method breaks the Law Of Demeter. The action code is still assuming that the user object contains a profile object and, even worse, it is making assumptions about what methods that profile object has. There should be a proxy method that allows:
$this->getUser()->getFirstName()
It is acceptable to call the user object since the user object is a member object of the current class. You can call its methods, but you should never call on objects inside of it. Rather, its methods should be smart enough to figure out what you want and get it for you, without you (or rather, your code) having to know the details of how that data is fetched. Hiding the details of implementation, at each level, is good object oriented design.
Symfony programmers obviously take their cue from the core team about what constitutes idiomatic Symfony code. Getting the idiom right is one of the theoretical advantages of using a framework - it allows other programmers to understand your code more easily.
There is a counter-argument to the Law Of Demeter, which is mentioned on the Wikipedia page:
A disadvantage of the Law of Demeter is that it sometimes requires writing a large number of small “wrapper” methods (sometimes referred to as Demeter Transmogrifiers) to propagate method calls to the components. Furthermore, a class’s interface can become bulky as it hosts methods for contained classes resulting in a class without a cohesive interface.
There is a balance of concerns here that programmers need to think about carefully. On the one hand, multi-level reaches through several objects leads to high coupling that makes the code brittle, difficult to change and difficult to test. But the alternative is to write hundreds of small methods which act as aliases for what you are actually trying to get (related to the Adapter or Facade pattern). Writing so many wrapper methods would be time consuming, and therefore expensive, at least in the short-term. So what is the right answer? I think it depends on the long-term ambitions of the project. If you are creating a site that is simple, or that will be unchanging, then it is probably best to go with what is quickest, which would be the multi-level reaches through objects that you see in a lot of Symfony code. But if you’re working on a project that is ambitious (perhaps you are working for a startup that hopes to become the next Facebook or Twitter), then it is best to give the long-term considerations priority over the short-term considerations. If the project hopes to scale up and add new features constantly, then you will need code that is flexible, code that can be changed often without breaking. The initial upfront time needed to write a bunch of wrapper methods will pay off over the long-term.
All the same, the truly best way forward would be for the Symfony framework itself to auto-generate more of these wrapper methods for us.
Hevery is also critical of context objects:
Most applications tend to have some sort of Context object which is the kitchen sink… It tends to have reference to just about every other class in your system, hence the compiler will need those classes too. This kind of code is not very reusable.
Even if you don’t plan to reuse the code, the Context has high coupling with the rest of the system. Coupling is transitive, this means Mechanic inherits all of the badness through association.
I’m looking at this project that I am suppose to refactor. I see many lines like this:
sfContext::getInstance()->getRouting()->getCurrentInternalUri()
This is another problem that derives from the lack of dependency injection in Symfony. For those types of sites where long-term considerations need to be given priority over short-term considerations of speed, the managed dependency injection coming in Symfony 2.0 will be very helpful.
The most serious mistake that I make in my own code is the over-use of statics, which the Google Engineers denounce strongly (remember, they are being sarcastic, so they are saying the opposite of what they mean):
Use Statics - Statics, statics everywhere! They put a great big crunch in testability. They can’t be mocked, and are a smell that you’ve got a method without a home. OO zealots will say that a static method is a sign that one of the parameters should own the method. But you’re being 3v1L!
Use More Statics - Statics are a really powerful tool to bring TDD Infected engineers to their knees. Static methods can’t be overridden in a subclass (sometimes subclassing a class and overriding methods is a technique for testing). When you use static methods, they can’t be mocked using mocking libraries (nixing another trick up the pro-testing engineer’s sleeve).
Create Utility Classes and Functions/Methods - For instance, you have a String which is a URL you’re passing around (obeying “Use Primitives Wherever Possible”). Create another class with static methods such as isValidUrl(String url). Don’t let the OO police tell you to make that a method on a URL object. And if your static utility methods can call to external services as well, that’s even better!
I’m glad to be called out on this one and reminded of the bad habits that I’ve fallen into. On each of my last 3 Symfony projects, I’ve written some custom functions for formatting dates. I made them all static methods of a Date class. The Date class was a pure utility class, without state. It holds nothing but static functions. I was cutting corners, for sure. At some level I was aware that this was only make-pretend OO design. It is good to be reminded that “a static method is a sign that one of the parameters should own the method”. This suggests that the methods really belong in the model classes wherever the data is coming from, or in the form class that first accepts the input. Assume I have a table called Questions and it has a field called “when_was_this_answered” which stores a Unix timestamp, then the model class Questions should maybe have the formatting method that turns that timestamp in a readable date. Of, if the dates are formatted depending on which time zone the user lives in, then the formatting methods probably belong in the user profile class.
The Google Engineers are also critical of helper functions, and especially on this issue, the Symfony framework is perhaps promoting bad practice:
Utils, Utils, Utils! - Code smell? No way - code perfume! Litter about as many util and helper classes as you wish. These folks are helpful, and when you stick them off somewhere, someone else can use them too. That’s code reuse, and good for everyone, right? Be forewarned, the OO-police will say that functionality belongs in some object, as that object’s responsibility. Forget it, you’re way to pragmatic to break things down like they want. You’ve got a product to ship after all!
Certainly, Symfony makes the use of helpers seem normal. The argument for them is that they are lightweight compared to auto-loading classes, and if you don’t need some helpers, then why include them? The argument against them is one that brings up long-term considerations, such as the hit matainability will take when you depart from OO design. One could argue that the helpers included in the Symfony framework are an exception since they are tested and vouched for by the core Symfony team, so as long as you are willing to trust the Symfony framework, you should be willing to trust the included helpers (a commenter on Potencier’s blog says “in symfony we trust”). But I think it’s safe to say that Symfony’s documentation encourages the use of programmer’s making their own helpers, and in that the Symfony project is possibly promoting bad practice (this summer I worked on a project that was initially headed up by an older, very experienced programmer. This was his very first Symfony project, and he read the documentation carefully. When I asked him why there were so many helpers, he suggested that he was trying to stay with the Symfony idiom).
Personally, I’d be happy to see all helpers removed from Symfony. The helpers used in the templates probably belong in a template or rendering class. Since Symfony 2.0 will have a new template enginge, 2.0 would be an appropriate release for the Symfony team to begin to deprecate helpers, while moving the funtionality to more appropriate places.
25 Oct
Fabien Potencier has stirred up a storm with his post about template systems. If you’ve got time, you might want to read the whole thing, plus all the comments at the end, many of which are well written. If you are short on time, I’m going to here summarize what I think are some of the best points.
It’s worth noting that Potencier is introducing a new PHP template system, called Twig, which will be natively supported in Symfony 2.0. So as you read his criticism of other template engines, understand that he’s explaining why he thinks his new system is best.
For me, the big suprise was to realize how much Potencier dislikes PHP. He is, after all, the lead programmer of Symfony, and Symfony, more than any other framework, aims to give the world the kind of strict MVC framework that will allow the corporate world to take PHP seriously. And, as far as I know, Symfony is the only PHP framework that has been used to build really big sites, like Yahoo Bookmarks and DailyMotion. Potencier seems to be one of the many programmers who admire the cleaness of Python relative to PHP. In his critique, he compares several PHP template engines to the Python-powered Django, and in every case he regards Django as superior:
I will take Django as an example of a modern template language in my examples for reasons you will understand later on, and mainly because I think Django template language hits that sweet spot I talked about above.
The Symfony project has seen this kind of Python-envy before. The first version of Symfony used Propel as its exclusive ORM, and Propel, in turn, relied upon Creole. But the lead programmer of Creole (Hans Lellelid) eventually gave it up and switched to Python, and, on his way out, he denounced PHP:
On more of a rant/stream-of-thought note, I wonder if PHP is ready for the next generation of web applications. It worked great for creating HTML templates, but are people building new applications today really using PHP to generate HTML? Maybe they are, but everything seems to be moving to a model where the backend is just a services layer. PHP doesn’t offer any advantages over other languages when it comes to a simple web services layer; heck, Java even starts to look easy if all I’m doing is writing a JSON-RPC server that talks to a database. The multiple-page model for serving requests no longer makes sense; instead you have some sort of front controller — so now you’re using a framework. And all of these languages have frameworks, but languages like Java and Python not only have web frameworks but have framework API standards. They’ve been thinking about this for a lot longer, and it shows. So I think that PHP as a solution needs to evolve at the engine level (with things like namespaces + built-in phar, etc.) AND it needs to evolve at the community level (with new standards and framework specifications). I’m not sure either type of evolution is really compatible with PHP’s democracy-driven development model.
Potencier criticizes 5 main things about PHP as a template language:
1.) A lack of concision
2.) A lack of a template oriented syntax
3.) A lack of reusability
4.) A lack of security
5.) A lack of a sandbox mode (a mode where untrusted users are free to write, unable to do harm)
Of concision, he offers this:
PHP becomes ridiculously verbose when it comes to output escaping (and yes, escaping variables coming from an unsafe source is mandatory nowadays):
<?php echo htmlspecialchars($var, ENT_QUOTES, ‘UTF-8′) ?>
Compare with the same examples written with the Django template language:
{{ var|escape }}
Of a template oriented syntax, he offers this contrast of PHP and Django:
<?php if ($items): ?>
<?php foreach ($items as $item): ?>
* <?php echo $item ?>
<?php endforeach; ?>
<?php else: ?>
No item has been found.
<?php endif; ?>The Django version is much better thanks to the use of an else clause for the for tag:
{% for item in items %}
* {{ item }}
{% else %}
No item has been found.
{% endfor %}
About reusability, he says he is looking forward to having ‘traits’ in PHP. See my last post for more about that.
Potencier seems to like the Smarty template system, but he mentions that it has terrible performance. He also lists these flaws:
* Not object oriented
* No template inheritance
* No sandbox mode
* No automatic escaping
His criticism of PHPTAL:
PHPTAL is a very nice project that implements the Zope Page Templates syntax. It is very well designed, supports lots of features, but is unable to render templates besides HTML ones, which can be a problem if you want to use the same language for emails, RSS feeds, and so on. Also, I think the syntax is not web designer friendly, especially when you use advanced features like template inheritance:
Of Calypso:
Calypso is an implementation of the Django Template Language in PHP….But, the author himself acknowledge that the implementation is flawed.
Indeed, the author of Calypso writes:
I have tested Calypso performance some weeks ago and have not been able to write on it before. Don’t use it please its fucking slow and cannot be optimized in the current architecture, because the template will NOT be parsed into intermediate PHP code. …Triple or higher inheritence may not work under some circumstances. Which sucks. I sadly have no time currently to fix any of the issues poping up with Calypso, so please don’t use it for anything production.
Once you understand how much Potencier admires Django/Python, you can understand where he is coming from when he introduces Twig:
When I started looking for a PHP template language, I focused on libraries trying to mimic the Django template language features. After many hours of Googling, I found Twig. Twig was written by Armin Ronacher of Jinja fame. Needless to say I have the uttermost respect for Armin as he does a wonderful job with Jinja.
He wrote Twig back in 2008 for Chypr, a blogging platform. But he never really developed it further as he mostly work with Python.
When I had a look at the code, I was immediately sure it was what I was looking for. The main difference with Calypso being the fact that Twig compiles the templates down to plain PHP code. I started to use it a bit and at the end of last week, I asked Armin if he wouldn’t mind letting the project starts a new life. His answer was enthusiastic, and so I began hacking the code. My version is much different from that of Armin, but the lexer and parser are mostly the original ones.
So, for Twig, Potencier lists these advantages:
Native template inheritance (templates are compiled as classes);
Solid automatic auto-escaping (with no associated runtime overhead as everything is done during compilation);
Very secure sandbox mode (white-list the tags, filters, and methods that can be used in templates);
Great extensibility: you override everything, even the core features, by bundling your own tags and filters as an extension; but you can also manipulate the AST (Abstract Syntax Tree) before compilation. By leveraging this possibilities, you can even create your own DSL (Domain Specific Language), targeted at your application.
In the comments, Vincent Cogne makes a point that I agree with, about the need of designers to be able to read the templates:
When working with a graphic team in charge of the integration of the website’s pages you must have a template system easy to use for a non-coder person. I think flow control and loops are to complicated in the template engines listed in this article. Designers don’t have to know the use of FOR AS structures. phpBB template Engine uses BEGIN/END key words which I found more handy.
I’ve found that if the designers can not work on the templates, then what you get in the end is a mediocre experience for the end user. There are a thousand small issues of usability that the designer tends to test and refine as they iterate a design - a process which becomes impossible if the designer has to wait on the programmer to make a change to the template. (This issue is important for content websites, but it is even more important for software/GUI issues.)
In response, Alex Farran makes a good point:
@vincent @Dominic I think your two comments sum up why template languages are such a difficult compromise. To keep it understandable to non-developers you have to restrict it to a very limited set of control structures. Too limited to be of much practical use. So you add features that turn it into a small programming language. Now your developers complain that they have to learn another language that doesn’t offer many advantages over PHP, and several disadvantages.
WishCow repeats the point about designers needing to edit the templates:
I’m completely against the “designers don’t have to know about foreach and stuff” mentality. They should totally know about it. It is a very simple, and easy to understand concept. Saying that one engine’s way of doing a foreach is nicer for a designer, is not reason enough.
I agree with this strongly. I’ve had the luck to work with some truly great designers. They usually have no problem learning enough PHP to read the templates. They are smart, and they need to have control over every graphical property of the GUI.
Miles Johnson offered strong criticism of the very idea of a template engine:
I in all honestly think template engines are garbage. I hate the fact that you have to basically “learn” a new language and syntax that can be easily written out as PHP. Secondly it will be slower then using regular PHP because it will have tons of parsing and possible regex to process. Thirdly its lack of support for the most basic of tasks, like not being able to use all of PHPs built in functions, is a total pain.
Chris.R says he would stop using Symfony if the new template engine were mandatory (but Potencier later insisted that Twig would never be mandatory):
If Symfony 2.0 forces the use of a template engine I will be back to looking for a framework, I know I am not going to change the symfony developers mind by making this statement, but you asked for feedback and here it is.
In response to some of the fears and concerns expressed in the comments of his first post, Potencier posted again, with some reassuring words about the value of pure-PHP templates:
Before I try to answer some questions, I’d like to re-state that I like PHP templates. And you should remember that symfony has only used plain old PHP templates since the beginning. As a matter of fact, I’m been advocating about using PHP templates since my first PHP project, and I have never used any other PHP template engines. So, I’m not against PHP templates; I just find that some PHP limitations as a template language are more and more irritating for me.
He also mentions a new Symfony template component that I knew nothing about:
If you are looking for a templating engine that only uses PHP and have built-in support for template inheritance, blocks, helpers, and some more, the good news is that I have coded one some weeks ago under the Symfony Templating Component name. It’s a standalone component, which has no other dependencies, and I’m sure most people wanting to use plain PHP for their projects will love this project.
It is hard to keep up with everything going on the world of Symfony. The new template component describes itself thus:
The Symfony Templating component provides all the tools needed to build any kind of template system. The Symfony Templating component is a thin and flexible layer on top of PHP that provides simple but powerful features, covering most templating common needs.
At first it seems confusing that Potencier is introducing 2 new template systems at the same time. However, I believe the goals are different: one uses pure PHP and one does not. And, if I’m not mistaken, everything over at components.symfony-project.org is meant to be refactorization of the technologies in Symfony, in particular, Symfony 2.0. So the new Symfony template component is probably the template module being de-coupled from the rest of the Symfony framework. (In the world of Symfony, there will never be a Merb rebellion, like there was in the Rails community, because the core Symfony team are their own Merb rebellion.)
Potencier tries to explain his motivations, again:
One of the key point of my reasoning is that a good template language should aim to find the sweet spot. The template language should find the best compromise about too many and not enough features. As I said in my previous post, the template language is all about presentation logic. And of course, simple conditions and loops are part of the presentation logic. But do you want to use array_chunk() in a template? Probably not. This call belongs to the controller or the model, depending on what you want to do.
A surprisingly intense argument opened up about how to handle output escaping. Potencier said:
Some commenters advocate that output escaping should be done in the controllers. That cannot work. As John Campbell writes: “The problem is that the controller can’t possibly be aware of the context of the output, nor understand which type of escaping is correct.” The issue is therefore not that simple. On the one hand, developers should take care of output escaping, but it cannot be done in controllers. On the other hand, web designers should not have to take care about output escaping, but templates is the only place where you have enough context information to apply sensible escaping. That’s why automatic output escaping seems the best compromise to me, plus the fact that being “almost” secure by default is a big advantage.
Several people wrote in the comments to suggest that output escaping does not belong in the templates, and should instead be handled in the model. Pádraic Brady wrote a reply to that argument:
The obvious problem with escaping for a View within a Model. The Model knows exactly nothing about the View. Why should it?
The Model is a representation of state, and the domain logic which acts upon that state. Whether an external actor wants to stick that state into HTML, XML, JSON, CSV, PHP, or any other format is its business. Therefore, only such an external actor actually knows the correct means of escaping the data it received from the Model, whether it is a Controller, or the View itself.
Unless, of course, you make the Model aware of the View. In which case, congratulations, you just broke one of the primary separations contained in MVC (check a UML diagram - the little arrow in the line connecting the View to the Model is a one way association).
Developers should note that “automatic escaping” within Views has been around for a long long time as a form of Poka-Yoke safe guarding. It’s about time PHP developers figured that out. Kudos to Fabien, it’s been part of Symfony for a long time now. I don’t completely buy the performance problems (I use it here custom implemented into Zend_View with no measurable performance hit), so nobody should be afraid to look into the implementation possibilities.
Such a debate opens my eyes to the range of template styles that are already in use in Symfony projects - there are well over a 100 comments on the 2 posts, with many Symfony developers expressing strong opinions about the various options.
For my part, I’ve always been an advocate of pure-PHP templates, and their use was one feature that I liked about Symfony. As for Twig, the only feature it has that I can ever imagine needing is the sandboxing, and then only if I’m asked to build the kind of site where random, untrusted users are allowed to create their own templates (perhaps an online social network where users are allowed to customize the look of their own profile pages).
But damn, it is impressive the way the Symfony team keeps coming out with interesting technologies.
24 Oct
Fabien Potencier writes:
PHP has greatly evolved over the years as far as reusability is concerned. Since PHP5, the object implementation is much better, and when traits will be supported in the next version of the language, we will have a solid general purpose language at our disposal.
I didn’t know anything about traits, so I went and looked at the RFC:
Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way, which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins. They are recognized for their potential in supporting better composition and reuse, hence their integration in languages such as Perl 6, Squeak, Scala, Self, Slate and Fortress.
I’d noticed that PHP had been drifting in the direction of Java, though I’d never seen it explicitly stated as a goal before:
Code reuse is one of the main goals that object-oriented languages try to achieve with inheritance. Unfortunately, single inheritance often forces the developer to take a decision in favor for either code reuse or conceptual clean class hierarchies. To achieve code reuse, methods have either to be duplicated or to be moved near the root of the class hierarchy, but this hampers understandability and maintainability of code.
To circumvent this problems multiple inheritance and Mixins have been invented. But both of them are complex and hard to understand. PHP5 has been explicitly designed with the clean and successful model of Java in mind: single inheritance, but multiple interfaces. This decision has been taken to avoid the known problems of for example C++.
The core team at Symfony wanted to introduce something like mixins, but they were up against the limits of the PHP language. As a partial workaround, way back in 2006, they introduced the sfMixin class:
New mixin feature. The sfMixin class introduces mixins in PHP, allowing core classes modification without inheritance, addition of new methods to existing classes, and multiple inheritance.
The sfMixin class has since become the main tool that allows for registering hooks in Symfony, the same mechanism which allows database/model behaviors. But sfMixin will always be only a half-way solution, as it is a class, and not part of the language. I think what Potencier is saying is that what PHP really needs is a feature in the language that allows this kind of code re-use, and he looks forward to seeing traits in the language for just this reason.
Traits are defined in even simpler terms than Mixins:
As already mentioned, multiple inheritance and Mixins are complex mechanisms. Traits are an alternative which have been designed to impose no additional semantics on classes. Traits are only entities of the literal code written in your source files. There is no notion about Traits at runtime. They are used to group methods and reuse code and are totally flattened into the classes composed from them. It is almost like a language supported and failsafe copy’n'paste mechanism to build classes.
If I understand this right, the goal of this simplicity is to avoid the explosion of methods that may constitute an anti-pattern of Mixins. As Michele Simionato argued in “Mixins Considered Harmful”:
Injecting methods into a class namespace is a bad idea for a very simple reason: every time you use a mixin, you are actually polluting your class namespace and losing track of the origin of your methods. In this sense, using a mixin in a class is just as bad as using from module import * in a module. However, everybody agrees that it is much better to use the full form mymodule.myname instead of importing all the names in the global namespace, but nobody realizes that importing methods into a class via a mixin is potentially just as bad. …To trace the origin of the methods and to keep in mind the hierarchy is practically impossible.
Those of us who make our living from PHP have a lot to gain from traits. They will give us the flexibility that other languages enjoy via Mixins, but traits have the advantage of not becoming part of the inheritance tree, and therefore they avoid the headaches of Mixins.
I am curious to see how Potencier, and the other core programmers, work this into Symfony. We can get a hint from Potencier’s newest project, the new template engine called Twig. Potencier says Twig will be supported naively in Symfony 2.0.
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.
15 Sep
We came across an interesting problem today when setting up an application we’d built earlier in a fresh dev environment to add some features…
Because we’re big fans of MySQL Workbench we made our initial schema changes there, generated the SQL to update the DB, then used a symfony propel:build-schema to generate an updated schema.yml followed by a symfony propel:build-model to update the model…
All good so far, until I began work on the first change and tried to fire off the task I’d just written…
Fatal error: Class 'BaseSMMConfig' not found in /usr/local/projects/smm/lib/model/SMMConfig.php on line 3
After some looking around, I realised my base class was called BaseSmmConfig - spot the problem? Yes, the ‘mm’ was lower case, while my class was looking for ‘MM’ in capitals…
So what caused this?
The application had originally been created by writing the schema.yml file (including the phpName being specified) then doing a symfony propel:build-all to create the DB and the model together. This is fine as the capitalisation used in the hand written schema.yml flowed through to the model. When I had done the reverse, creating a schema.yml from the DB, all it has to go on is the names of the tables, using camel case to identify where an underscore exists in the table name, so the ’smm_config’ table becomes SmmConfig in the schema.yml and model, not SMMConfig as originally typed. Because your extendable model classes don’t get updated (so as not to overwrite your changes) your app then breaks down.
So the lesson:
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