Single comments causing errors in PHP

Viewed 45

I am very embarrassed right now. I thought all the comments were working the same way. But I found out that // and # are different from multi-annotation like /* */

/*$conText = preg_replace_callback('@(<a .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>(.*?)</a>)@si', create_function('$matches', 'return addLink($matches, 1);'), $conText);
$conText = preg_replace_callback('@(<area .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>)@si', create_function('$matches', 'return addLink($matches, 0);'), $conText);*/

//$conText = preg_replace_callback('@(<a .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>(.*?)</a>)@si', create_function('$matches', 'return addLink($matches, 1);'), $conText);

$conText = preg_replace_callback('@(<a .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>(.*?)</a>)@si', 'fnConText1', $conText);
$conText = preg_replace_callback('@(<area .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>)@si', 'fnConText0', $conText);

If there is an // code, there will be a syntax error, but if you delete the line, there will be no error. Do you happen to know why this error occurs?

1 Answers

This is actually rather subtle, but can be seen more clearly with a simpler example:

<?php 
echo 'hello'; 
// This is a comment with '?>' in
?>

Which results in this:

hello' in
?>

At a glance, it looks like the first ?> is part of the comment, and the <?php block will continue until the second one (and at the time I write this, the site's syntax highlighter assumes so); but PHP doesn't parse it that way.

To see why, consider this example:

<?php echo 'hello'; // this is a comment ?>

This is a self-contained piece of PHP which you could embed in a template file, with a comment contained inside the <?php ... ?> block. If the comment suppressed the meaning of ?>, this wouldn't work.

So rather than "comment until the end of the line", // is defined as "comment until the end of the line or the end of the current PHP block, whichever comes first".

In contrast, a block comment is defined as ending at its own */ marker, so the following does comment out the first ?>:

<?php
echo 'hello';
/* This is a comment with '?>' in */
?>

Output:

hello

In your case, you effectively have this (with some other code before and after):

<?php
//$conText = preg_replace_callback('@(<a .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*?>(.*?)</a>)@si', create_function('$matches', 'return addLink($matches, 1);'), $conText);
?>

Buried in the commented out line happens to be the characters ?>. The parser doesn't look at the rest of the syntax, because it's a comment, but does pick up those characters as ending the PHP block.

The result is that PHP interprets it essentially as this:

<?php
//$conText = preg_replace_callback('@(<a .*?href\s*=\s*(([\'"])(.*?)\3|([^\s>]+)).*
?>
(.*?)</a>)@si', create_function('$matches', 'return addLink($matches, 1);'), $conText);
?>

That leaves the end of the line which you were trying to comment out, and everything after it, as text to be output rather than code.

Related