Symfony2: Annotations get better
May 23, 2011 • Published by Fabien Potencier
Later today, I will release Symfony2 beta2. But first, I wanted to talk about a big change that landed into master yesterday. As you might know, Symfony2 uses annotations for Doctrine mapping information and validation configuration. Of course, it is entirely optional, and the same can be done with XML, YAML, or even PHP. But using annotations is convenient and allows you to define everything in the same file.
Symfony Standard Edition provides an even better support for annotations via
two additional bundles: SensioFrameworkExtraBundle
and
JMSSecurityExtraBundle
. They allow you to use annotations for controller
configuration (routing, cache, security, template, ...).
To avoid ambiguities when different libraries/bundles define new annotations, you were required to use a configurable "prefix":
/**
* @orm:Entity
*/
class User
{
/**
* @orm:Column(type="string", nullable=false)
* @assert:NotBlank
*/
private $name;
}
But several problems arose quite fast:
If you have a look at the Doctrine documentation, you will see that
@Column
is used instead of@orm:Column
. That's because the prefix is optional. So, the Doctrine documentation does not use one, but Symfony2 forces you to useorm
. Note that it is configurable, so you might use any other prefix (@doctrine:Column
).The annotation library did not play well with autoloading.
SensioFrameworkExtraBundle
andJMSSecurityExtraBundle
shared the sameextra
prefix, but it was a hack and it was not really scalable.
Johannes worked hard in the last few weeks to find an elegant solution to this problem. As each annotation is defined as a class, instead of using only the short class name, we have decided to use the fully qualified class name. It removes the need for arbitrary prefixes defined as a global configuration, avoids any ambiguities between libraries, and gets rid of the autoloading issue altogether:
/**
* @Doctrine\ORM\Mapping\Entity
*/
class User
{
/**
* @Doctrine\ORM\Mapping\Column(type="string", nullable=false)
* @Symfony\Component\Validator\Constraints\NotBlank
*/
private $name;
}
Of course, using the FQCN everywhere is quite verbose but fortunately, PHP
already has a solution via the use
statement:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*/
class User
{
/**
* @ORM\Column(type="string", nullable=false)
* @Assert\NotBlank
*/
private $name;
}
Annotations now feel more "native". If you want to use annotations outside of a Symfony2 context, have a look at the Doctrine Common repository (version 3.0).
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
And still no default= option?!
Someone tried generating a documentation with such annotations included?
We havent discussed finally what features become deprecated and which will make the step to 3.0
Although I've saw its now called 'Symfony Standard Edition'.
Please please please please please tell me that symfony isn't going to have a 'standard' and 'premium' edition...
I'd expect that parsers can adapt (except for perhaps the older ones) but a detailed specification of the new format is necessary. I know I wouldn't mind adapting DocBlox but I'd need the spec.
The format above also conflicts with efforts in Internals where a different format is proposed for a similar functionality. Perhaps you and Guillhermo can work together to come to a single standard?
For one it does not mention the use of non-alphanumeric character as tag names.
And additionally it present that content in the 'description' section of the tag; whilst the above code shows no space between the @tagname and the (content). This does not help when generating documentation as a tag is no longer an identifier but now has contextual meaning and thus countless variations.
For example there could be a "Rest Server Edition" or a "CMF Edition" that come preconfigured with relevant Bundles, libs and settings.
Less wtf's..
Awesome idea =)
Is there anyone with C and PHP internal skills, who can implement this missing feature, so that it can be merged into PHP5.4!?