website stat

PHP IL Bashing

Update: To be fair, this behavior can also be seen on Rails for instance. Since it's not only with PHP I extend this post to PHP-and-others-that-show-the-same-behavior. Everything on a one-line comment should be dumped until a newline character is found. IMHO.

Inside a PHP file, you have something like this

PHP:
  1. <?php
  2.  
  3. // <?php some_function(); ?>
  4.  
  5. ?>

It's commented. It is NOT to be parsed. Why the heck does it get parsed and executed then? Using PHP 5.2.0.

Yes, you can try using the pound sign (#). Same behavior.


22 Responses to “PHP IL Bashing”

  1. Pedro Timóteo
    Published at May 17th, 2007 at 9:05 pm

    You should comment it *inside* the php tag, I guess. PHP doesn’t look outside the tags, so it can’t guess it’s supposed to be commented.

  2. mlopes
    Published at May 17th, 2007 at 9:12 pm

    That’s not correct.

    If you just remove the < ? ?> tags it won’t try parsing the content nor it generates any kind of error.

    Also, the comments are inside < ? ?> tags, not left alone in the PHP file, so another reason for not being parsed.

  3. André Medeiros
    Published at May 17th, 2007 at 10:30 pm

    Everything outside the block is considered direct output. From what I could gather, that is the sittuation.

    And no, that comment in particular is not inside tags, unless you have short_tags disabled on your php.ini

  4. Filipe Correia
    Published at May 17th, 2007 at 11:08 pm

    Sory I’m not sure I understood your last comment. However, I can tell you php is doing the right thing there; a php file with those contents should output the text “//” followed by the result of “some_function()”.

    Php comments are only valid inside php blocks. Anything outside php blocks is treated as text to be outputted as is.

  5. mlopes
    Published at May 17th, 2007 at 11:25 pm

    That line was inside a PHP block.

  6. Bruno Pedro
    Published at May 17th, 2007 at 11:49 pm

    I cannot hold myself from commenting again.

    First of all your assumption is wrong. The some_function() call is not executed because it’s not even parsed because it’s a comment.

    The correct output of your script is:

    ?>

    Why is this the output?

    Again, if you read the manual you would understand that (quoting):

    “The “one-line” comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after // … ?> or # … ?> WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and // or # cannot influence that.”

    Which means that the comment ends at the ?>, and everything thereafter is treated as HTML or even another block of PHP code.

  7. Pedro P
    Published at May 17th, 2007 at 11:57 pm

    Use /* */ to comment it out my guess is that the line #3 ?> is causing the problem because in php4 you can close the tags inside a comment.
    Anyway your code makes no sense you should close the tag before opening a new one.

  8. mlopes
    Published at May 18th, 2007 at 12:04 am

    But what’s the point in that? The first ?> is not the closing tag and *it’s commented*.

    Honestly, is there a valid reason for such behavior? What’s the logic of parsing a comment?!

    It has nothing to do with reading the manual whatsoever. The behavior is simply dumb until proven otherwise.

  9. mlopes
    Published at May 18th, 2007 at 12:07 am

    Pedro P,

    The code was for demonstration purposes only. Point I was trying to make was that the commented code was being parsed.

    Anyway, when I first implemented a language compiler the first thing I’d do was dump all the comments.

    I really don’t get the point in considering what’s inside a comment. This way it is *not* a comment but rather a piece of code that looks like a comment. Obnoxious.

  10. Bruno Pedro
    Published at May 18th, 2007 at 12:23 am

    Again:

    “The “one-line” comment styles only comment to the end of the line or the current block of PHP code, whichever comes first.”

    Is it clear now? The commented code is *not* being parsed.

    The comment *ends* at the ?> (end of code block).

    Yes, the end of code block sign (?>) is interpreted even inside a one line comment.

    Why does PHP behave like that? The parser simply stops PHP interpreting *whenever* it finds the end of code block sign (?>, in this case).

    It’s an implementation decision. Remember that, unlike other scripting languages, PHP allows mixing blocks of code and HTML inside the same document.

  11. mlopes
    Published at May 18th, 2007 at 12:41 am

    Bruno,

    Yeah I got that.

    I noticed that this also happens with Rails.

    Honestly, I don’t get it. I’d definitely ignore everything after a // or # until a newline is found. I don’t see much value in being able to start/end interpreted code in the middle of a comment.

  12. Nuno Mariz
    Published at May 18th, 2007 at 5:56 pm

    Yes, is stupid. Along with other things in PHP.
    BUT, Why the hell do you what to put inside another? Makes no sense.
    If you want to maintain this crappy code, use /* */ instead.

  13. mlopes
    Published at May 18th, 2007 at 5:59 pm

    Nuno,

    I was just commenting some stuff out not for the sake of commenting but temporarily. I noticed a very weird error then and I was like “What, PHP considers what’s inside a comment?!”

  14. Marco Rodrigues
    Published at May 18th, 2007 at 9:32 pm

    Try to report is as a bug at http://bugs.php.net

    To see their answer…

  15. Sergej 'ZaZa' Kurakin
    Published at May 19th, 2007 at 4:14 pm

    Cite from “Zend PHP 5 Certification Study Guide”:

    Both types of single line comments, // and #, can be ended using a newline (\r, \n or
    \r\n) or by ending the current PHP block using the PHP closing tag — ?>.

  16. Sergej 'ZaZa' Kurakin
    Published at May 19th, 2007 at 4:17 pm

    Sorry, for second comment.

    I think, this cite is the answer, witch you will get on your bug report and, of course bogus status .)

  17. mlopes
    Published at May 19th, 2007 at 7:35 pm

    Sergej, thanks for the insightful comment.

    I was not planning to file a bug since I know it was a decision by the PHP team. I just don’t understand that decision (same applies to Rails it seems).

  18. Sergej 'ZaZa' Kurakin
    Published at May 20th, 2007 at 9:25 am

    I think, that we shouldn’t think about WHY they do so (probably we will never know and understand why they decided to do so), we just must remember how to use this feature.

  19. mlopes
    Published at May 20th, 2007 at 10:20 am

    Well, you call it feature, I call it a huge bug. It’s counter-intuitive. Who would have thought about ending PHP code inside a comment? Damn, a comment is a sacred thing. *Nothing* happens (or should happen) inside a comment.

  20. Sergej 'ZaZa' Kurakin
    Published at May 21st, 2007 at 7:26 am

    Yes, you are, possibly, right.

    In my 6 years of PHP practice I never met this problem. This is first time. Yes I use comments, but often it is /* … */, and some times it is inline, but my ?> (php block end mark) is always on next line.

    IMO, inline comments and PHP code end block handled so, because, possibly, someone could use something like that: &lt?php [somecode]; // soem comment ?> inside HTML code, and by you, this will cause error.

    And, if we will watch the PHP manual, we will find, that /* … */ style comments handling are not perfect to.

    Maybe, some day, they will fix it.

  21. mlopes
    Published at May 21st, 2007 at 7:32 am

    Usually I avoid /* */ because you can’t do nested comments. So if you have a comment and then you want to momentarily comment a piece of code you’ll have to remove the inner comment ending tag (*/).

    Anyway, I came across this bug when doing precisely that. I wanted to comment something inside PHP code and, boom, that shows up.

  22. Sergej 'ZaZa' Kurakin
    Published at May 21st, 2007 at 8:14 am

    /* … */ comments I use for phpDocumentator comments or some notes in code.
    I never (ok, not often) use /* … */ to comment code, I use if (false) { [code] } blocks. Unused code removed before every commit to repository.