Annotations are all the rage in some PHP circles these days, but I don’t like them. I try to avoid them as much as possible, and I hope that my reasoning for doing so is justified.
What are annotations?
Annotations are a form of meta-code; in practice, they allow you to modify attributes and behaviors of your methods and classes in fast and convenient ways. Three common uses for annotations in symfony2 are routing, validation, and ORM binding – although regular users of PHPUnit will also be familiar with annotations for data providers and test grouping.
Why are they awesome?
Annotations do have some good qualities. They allow you to reduce the clutter of your projects by folding various configuration and behavioural information into the class itself. For example, the average symfony2 bundle has a validation.yml and routing.yml file – both of these files can be eliminated or reduced in complexity by using annotations.
Additionally, annotations allow you to design and maintain your projects in a more straightforward manner. Instead of having to open one class file and a handful of configuration files (or a handful of supporting classes), all the information is right there within the primary class file.
You might be interested in this article on how to build custom PHP annotations, to see some of the power and flexibility they can bring to your projects.
Why am I avoiding them?
I must confess that I have a semi-irrational paranoia about using annotations. However, I feel that there are also some rational reasons to consider avoiding them.
One such reason is that the decentralization of certain types of configuration can lead to oversights and possible repetition of unanticipated mistakes, which can cause behavior that is unpredictable and hard to catch and debug. While the term “decentralization” might seem out of place when talking about merging code and configuration together, it helps to remember that a symfony2 bundle (or any PHP project) can have many controllers and classes and entities. You might end up with two controllers fighting over routing (an easy-to-solve issue, I’m sure), or you might find yourself struggling to remember a route name and which controller handles it (a situation where a single routing definition can help your code be more self-documenting).
There are also some speed concerns with annotations, due to the heavy use of Reflection, but they are mostly alleviated through the proper use of caching.
Most importantly, I feel that it is wrong to have what amounts to program logic tucked away in what otherwise looks like simple comments. If PHP had an official non-comment-like notation for annotations, I might be more inclined to use them. As it stands, I only use annotations in unit tests at the moment – not in the main/production code.
That’s pretty much the crux of what I don’t like about them: I do not like using comments as code.
How about you?