7 ms·
PHP Annotations Are a Horrible Idea
- risratorn 14y ago> the PHP community is now officially so desperate for better metaprogramming capabilities that it is attempting to do so using code comments This says it all ... and to be honest, from an ease point of view I like using annotations but as with most parts of PHP it's the implementation that sucks (or the lack of implementation) Over 2 years ago a RFC has been filed for native php annotations and I must say that I like the idea of annotations being part of the actual language and not relying on Inflection on comments (wtf?) to attach metadata to classes, propeties or methods. Just too bad nobody can get their act together and get it implemented in the core. https://wiki.php.net/rfc/annotations https://wiki.php.net/rfc/annotations
- blowski 14y agoThat somebody could be you!
- risratorn 14y agoProblem is not finding someone to implement it, problem is getting the core devs on one line concerning the syntax/implementations. There have been numerous suggestions but none were deemed good enough, and maybe for good enough reasons I might add. http://marc.info/?l=php-internals&m=130496081925265&w=2 http://marc.info/?l=php-internals&m=130496081925265&...
- glazskunrukitis 14y agoI completely agree with you, but I would use something like this - http://pastebin.com/embed_iframe.php?i=U4Fmm0t6 http://pastebin.com/embed_iframe.php?i=U4Fmm0t6 I don't think that just an array quite make it as a real alternative but a definition builder called from a method seems more appropriate. Also I would seperate model definition from model repository.
- michaelmior 14y agoThis could be solved if annotations were supported syntax. This works well in other languages (e.g. decorators in Python and annotations in Java)
- masklinn 14y agoAnd before annotations were added in java, the exact same hack was used for annotations. The alternative was to have separate configuration and mapping files which was painful. And then, you had libraries which did not have in-comment annotations and intermediate ones which compiled in-comment annotations to the original libraries's mapping files. Oh the fun we had.
- willvarfar 14y ago(Python 3 has function argument and return annotations too) I've made a static type checker for Python... https://github.com/williame/obiwan https://github.com/williame/obiwan
- jawngee 14y agoThis is pure horse pucky. First of all PHP isn't about elegance and I find it a teeth grinding experience when people complain about it not being so. PHP is about getting stuff done. He doesn't offer one good valid technical reason why not to use comments for meta-programming PHP other than "it just feels wrong" and an "icky feeling" which is entirely subjective. "Reliance on Yet Another Library"? C'mon. The fact that you can even parse out comments with the reflection API lends, to me, that meta-programming is a-ok. Also, his alternatives are kind of weak. Here's an annotation: /** * @Column(type="string", length=32, unique=true, nullable=false) */ protected $username; And here's his proposed alternative: class User { public static $mapping = array( 'username' => array( 'type' => 'string', 'length' => 32, 'unique' => true, 'nullable' => function() { // Some logic to determine value. } ) ); } I'll take the first one because I have other shit I need to do.
- risratorn 14y agothe official RFC for annotations is actually a little cleaner in syntax, easier to read and implemented in the language itself which is a way beter system than comment annotations. On a level I do agree that docblock comments are no place for annotations, it's the best we can have for now though, just until annotations become a native PHP feature. Judging from the RCF and discussions on internals we still have a long way to go before we get annotations in PHP core. http://marc.info/?r=1&w=2&q=b&l=php-internals&s=annotations http://marc.info/?r=1&w=2&q=b&l=php-internals... https://wiki.php.net/rfc/annotations https://wiki.php.net/rfc/annotations
- masklinn 14y ago> the official RFC for annotations is actually a little cleaner in syntax, easier to read and implemented in the language itself which is a way beter system than comment annotations. Sure, everybody knows that, but when the language does not have actual annotations yet (in whichever form they are), in-comment annotations are a very common choice. That's also what Java libs tended to use before annotations were added in Java 5.
- orangethirty 14y agoAgreed. A comment is an explanation about some part of the program. Not the program itself. Its meant to be ignored by the computer. Putting logic in the comments is just downright stupid. Its one of those overly "clever" things "smart" people do to make their code be cutting edge. Nope. As good as Symfony is, my main issue comes down to design decisions as this one. Its just dumb. Having logic in comments its like putting beer in baby formula, just in case I run out of beer. Shit doesnt make sense.
- LeafStorm 14y agoAnnotations are not required to use either of those libraries. Doctrine allows mapping information to be defined in XML or YAML files. For Symfony, the @Template annotation is not part of the core at all: it is part of the SensioFrameworkExtraBundle, which can be turned off easily. The normal way to render a template is: return $this->render("MyBundle:Controller:template.html.php", array(...)); That said, it would be easy enough to add the static variable-based mapping information to Doctrine as a metadata driver, and create a version of SensioFrameworkExtraBundle that does the same for its annotations.
- dschiptsov 14y agowhile (true) read("http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/");
- pmelendez 14y agoI found this very ironic. I see PHP Annotations as a hack for comments. That said, I found very ironic someone giving a rant of a hack in hacker news. Just saying.. :)
- xentronium 14y agoThere are hacks and then there are crutches.
- yuri41 14y agoClosures inside property initializations inside the class body don't work. Not even in an array. So this code throws up a "Parse error: syntax error, unexpected 'function' (T_FUNCTION)" class User { public static $mapping = array( 'username' => array( 'type' => 'string', 'length' => 32, 'unique' => true, 'nullable' => function() { // Some logic to determine value. } ) ); }
- stevencorona 14y agoCame here to post the same thing. I don't know if it has been fixed in 5.4, though.
- robryan 14y agoNope, the parser seems to be pretty brittle around this. Someone who knows more about the internals can probably explain why this works: class User { public $mapping = array( 'username' => array( 'type' => 'string', 'length' => 32, 'unique' => true, ) ); public function __construct() { $this->mapping['nullable'] = function() { echo "test"; }; $this->mapping['nullable'](); } } $user = new User(); And this doesn't: class User { public static $mapping = array( 'username' => array( 'type' => 'string', 'length' => 32, 'unique' => true, ) ); public static function set() { self::$mapping['nullable'] = function() { echo "test"; }; self::$mapping['nullable'](); } } User::set();
- TazeTSchnitzel 14y agoI used to be interested in helping fix PHP, but I gave up. The reason is because Rasmus and a few others seem to think that using the syntax definition to do your type checking for you is a good idea, and that the hundreds of possible cases they didn't think of, don't matter.
- 14y ago
- blowski 14y agoWhat's in the annotation is configuration, not application logic. As such there's no real difference between putting configuration into YML, XML and annotation comments. In response to your 4 specific criticisms: 1. (DX regressions) - in theory yes, in practice the frameworks are good at this. The annotations compile down to PHP which you can look at directly, and you get exceptions if there is something wrong with the annotation. 2. (Decreased readability) - subjective POV. I find it easier, because the relevant configuration is next to the code to which it applies. It also prevents crufty out-of-date comments floating around. 3. (Yet another library) - Yep. No answer there. 4. (Icky feeling) - I get far more icky feelings out of seeing 30 lines of custom written 'setup code'. Annotations help to prevent that.
- jentulman 14y ago3) In this specific case we're reliant on Doctrine to read Doctrine annotations because we're already reliant on Doctrine to be Doctrine. Possibly relevant if the annotation reader was purely collecting metadata it did not use itself.
- theunraveler 14y agoNot necessarily. Several Symfony components rely on doctrine/common simply for parsing annotations, even if you are not using Doctrine for anything else.
- mmcnickle 14y agoI would argue that it's better for configuration and application logic should be separate though. You can run the same appliation with a different XML configuration without modification of the source. You couldn't do the same with in-comment configuration.
- troels 14y agoDX - As in Developer Experience? That's a first for me.
- EugeneOZ 14y agoComments should be comments only, but your code in "alternative" is very dirty. Static(!) public(!) property is violation of encapsulation.
- theunraveler 14y agoI don't understand how. It's a static property because it applies to all object of the class, not an individual object (i.e. an individual object shouldn't be able to change it). And how is making the property public a bad idea? The configuration system that parses it will need to read the property, no? And a method like getUsername() should be reserved for actually getting the value of that field, not its config.
- EugeneOZ 14y ago"It's a static property because it applies to all object of the class, not an individual object" Why? if you will have 3 databases, each will have same password? "And how is making the property public a bad idea?" Because it's breaks encapsulation. Also, there is two kind of "class" usages in PHP: as Object and as Structure. If your class is just Structure (contain no methods at all), then, of course, public properties is what we need. But when your class is an Object, which should have instances, API, then keep all properties encapsulated.
- willvarfar 14y agoSomewhat related, I recently made a simple type annotation library and checker for Python 3... https://github.com/williame/obiwan https://github.com/williame/obiwan Static type checking for Python yeah!
- shocks 14y agoYou don't need to use annotations with Symfony2. You can use yaml or xml configs if you want. I have a big project written with Symfony2 - not a single annotation to be found.
- methodin 14y agoI fail to see how an array makes debugging say a routing directive easier. The issue is generally incorrect names or values which will not be aided by a backtrace or a var_dump - you know the value in either scenario. You will still have to dive into the parser and understand what it's looking for to resolve your problem or delve into XDebug. In the situations when knowing the value of something does not help, I do not see why annotations wouldn't be superior.
- theunraveler 14y agoAt least you would know if your array contains a syntax error. With an annotation, you would have no way of knowing that aside from what the annotation parser spits out.
- ludovicurbain 14y agoThat article misses the point: PHP OO is a HORRIBLE IDEA. if you're doing OO PHP, shoot your other foot right now and go learn PHP before using it java-style. Why is it that every time somebody on HN explains that a technology is not suitable for a use case, it gets downvoted by fans of said technology ?
- theunraveler 14y agoWhy is PHP OO a horrible idea?
- ludovicurbain 14y agoPHP OO is broken in many ways (of which you can find a list in the blog post "php a fractal of bad design" PHP is naturally (due to it's C libs) non-OO and will thus only implement OO "that" far. Lastly, OO is not a silver bullet and is best used only in front-end, and languages that were designed with it in mind.
- theunraveler 14y ago> PHP OO is broken in many ways (of which you can find a list in the blog post "php a fractal of bad design" Agreed. Although the problem is more that PHP in general (not just its OO features) is really broken. > PHP is naturally (due to it's C libs) non-OO and will thus only implement OO "that" far. I have no idea what you mean here. AFAIK, there is nothing about C that prevents PHP from properly implementing OO principles. In fact, Ruby is written mostly in C and is completely OO. > is best used only in front-end What? > and languages that were designed with it in mind Sure, I guess...
- shakesbeard 14y agoWell, OOP in PHP seems to work rather well for thousands of large projects out in the wild - making your argument invalid.
- ludovicurbain 14y ago
- sandfox 14y agoSeriously, what sort of argument is this... (Allow me to paraphrase) "PHP doesn't have annotations, so instead it has hacked up comments that stand in for annotations. I find these ugly because it's abusing comments/etc therefore the idea of having a non-ugly real implementation that removes most of my objections is a bad idea" --EDIT I may have slightly not realised it was just comment annotations that were the problem here rather than annotations as a whole.... HOLD FIRE.
- theunraveler 14y agoI added an update to the article. I wasn't aware of the RFC to make annotations a language feature when I wrote the article. The article is specifically referring to annotations implemented as code comments. Sorry for the confusion, and thanks for your comment.
- f1gm3nt 14y ago"Without the special @Template comment, Symfony does not know where to find the template file." First off, this is completely false. With symfony2 the action needs to return a Response object. This annotation isn't required and the team I work with, we rarely use this. It's very useful for when you are just adding a page that contains no real business logic. "Doctrine 2 does the same thing when declaring object properties based on database table columns1:" Oh look, there's a footnote. "Fortunately, Doctrine also allows you to declare property metadata using PHP, YAML, or XML" What? "Because code comments should never be necessary for a script to function properly" So your points are that we need @Template annotation to be able to render a template, which is FALSE, and you state the same with with Doctrine2 which you point out there are other ways to do it. All your points for "DX Regressions" are completely wrong. Unless I am using a special plugin with my IDE it's not going to link "AcmeBlogBundle:Post" to src/Acme/BlogBundle/Entity/Post.php. Most of what you point out is complete bullshit. What do I gain to hope by using var_dump() on an annotation? I know that in a Doctrine Entity that the column type is a string. Articles and posts like this drive me banana's with the complete lack of understanding what you're writing about.
- theunraveler 14y ago> First off, this is completely false. With symfony2 the action needs to return a Response object. This annotation isn't required and the team I work with, we rarely use this. Correct. But if you want use the form where you just return an array of variables to use inside your template, and have Symfony smartly located the template for you, you have to use an annotation. See http://stackoverflow.com/questions/12922827/symfony-2-php-templates-autoloading http://stackoverflow.com/questions/12922827/symfony-2-php-te... for an example. > and you state the same with with Doctrine2 which you point out there are other ways to do it. Yes, there are other BETTER ways to do it. Making comment-based annotations available as one of the ways pretty much guarantees that people will use it, and that seems like a bad idea to me. Just remove them so no one is able to choose the bad practice. > All your points for "DX Regressions" are completely wrong. Uhh, OK? How about comment folding in text editors? Would you, as a developer, be happy if you encountered some code that made heavy use of annotations for critical application logic? I wouldn't--this is what I mean by DX. > What do I gain to hope by using var_dump() on an annotation? The same thing you gain by var_dump()ing any variable--an understand of what's happening under the hood.
- PaulHoule 14y agoFor me a lot of the fun in PHP in the last few years has been balls-to-the-walls metaprogramming.
- daGrevis 14y agoAnnotations (or decorators) are good idea as it is — they are very popular in Python. The bad part is that they are implemented horribly — as comment which are later parsed. This should be implemented in PHP core or at least someone should write extension for it. That would solve implementation problems and add new, good feature to PHP language.
- porker 14y agoCouldn't agree more. Every time I use annotations I feel dirty... Programmers who talk so much about code separation, clean modular structure etc are the same ones are willing to use annotations. What got into them? Disclaimer: I like code to be elegant. And practical. This is PHP we're talking about, but no need to do more bad choices...
- datasage 14y agoHaving used both doctrine and used a format of array mappings, I prefer the doctrine way of using annotations. However I do also acknowledge that putting important information into comments can be somewhat dangerous. Doctrine does support storing metadata in yaml and xml files too, but in that case you need to ensure that changes to your model class get reflected in the mapping file.
- sproketboy 14y agoPHP Is a Horrible Idea - FTFY
- Joeri 14y agoI've just ported java's bean vaidation to PHP using annotations in comments, and I strongly disagree. Point by point: 1. dx regressions I've designed the annotation system so that if developers misdeclare them an exception is thrown. Unit tests will fail, and the software will not run. Someone checking in code that fails to such a degree deserves what's coming to them. That covers php -l. Var_dump and debug_backtrace are irrelevant to my use case, and I use proper breakpoints and watches anyway (phpstorm + zend debugger). I don't even understand the point he's trying to make about IDE linking. Which leaves the argument about comment folding, which I think has some merit, if you think comments shouldn't be read, which I don't. 2. Readability Nonsense. Learning an API always requires getting used to its idiosyncracies. His proposal to use static variables looks less readable to me. 3. Reliance on another library Yes, that's kind of the point. 4. Icky feeling Aha, bingo. The author came in with the opposite bias of myself and drew an according conclusion. To conclude: the use of annotations in comments is not better or worse than alternatives, it's all in the eye of the beholder.
- gview 14y agoFirst of all, annotations are nothing new. They have been around in Java for years, and it was emulated because it had advantages that really don't need to be regurgitated by me. If they weren't a good idea, they wouldn't have lead to a formal adoption inside the language. Secondly, in both Symfony2 and Doctrine2, annotations are an OPTION. You use them if you want to use them, and if you don't want to, you can use traditional configuration files. It doesn't seem that the author has done anything with either Symfony2 or Doctrine2, or he would have understood that. As someone who used Symfony1, ZF1, Propel and Doctrine, I would not go back to the old way of doing things, even if I was offered good money to do so (as happened just last week in fact). Most people who actively use these components LOVE annotations, because they allow you to keep the configuration close to the code, and reduce verbosity. They drive code generation, and reduce the amount of code that has to be written to get a specific job done. So if there's a problem debugging, is it really about annotations, or about code generation, and if we can't have code generation (facepalm) then I suppose we shouldn't have template systems like smarty or twig, simply because "debugging is harder" and editors have more work to do. If it's not the author's cup of tea, nobody is forcing anyone to use these capabilities. Needless to say, I couldn't disagree with the premise of this article more. @jawngee already provided a simple salient example.